gusmanwidodo/auth-kit-credentials

Identifier + password login for Auth-Kit: register, login (email/phone/username + password), and forgot/reset password. Flexible single-identifier model, hashed passwords, single-use hashed reset tokens.

Maintainers

Package info

github.com/gusmanwidodo/auth-kit-credentials

pkg:composer/gusmanwidodo/auth-kit-credentials

Transparency log

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.0 2026-08-26 03:32 UTC

This package is auto-updated.

Last update: 2026-08-26 03:41:36 UTC


README

Identifier + password authentication for Auth-Kit: register, login (email / phone / username + password), and forgot / reset password. This is the fundamental credential login the ecosystem was missing.

Tests License: MIT

Features

  • Register with a flexible identifier (email / phone / username) + password.
  • Login with any configured identifier type; passwords hashed via Laravel Hash (bcrypt/argon per your app's config).
  • Forgot / reset password with single-use, expiring, hashed reset tokens.
  • Timing-safe login — unknown identifiers still perform a hash comparison so response timing does not reveal whether an account exists.
  • No user enumerationforgot-password responds identically whether or not the identifier exists.
  • Composes with the rest of Auth-Kit: a registered subject can then get roles (permissions), join organizations/teams, and link social accounts.

See ADR 006.

Requirements

  • PHP ^8.3
  • gusmanwidodo/auth-kit ^0.1
  • Laravel 12

Installation

composer require gusmanwidodo/auth-kit-credentials
php artisan migrate
php artisan vendor:publish --tag=auth-kit-credentials-config

Endpoints

Method URI Body
POST /auth-kit/credentials/register { identifier, password, type? }
POST /auth-kit/credentials/login { identifier, password, type? }
POST /auth-kit/credentials/forgot-password { identifier, type? }
POST /auth-kit/credentials/reset-password { identifier, token, password, type? }

type is one of the configured identifier_types (default email; also phone, username). Omit it to use the default.

Usage

use Gusmanwidodo\AuthKitCredentials\CredentialManager;

$auth = app(CredentialManager::class);

// Register (email by default)
$auth->register('user@example.com', 'secret123');

// ...or with an explicit type
$auth->register('+628123456789', 'secret123', 'phone');
$auth->register('gusman', 'secret123', 'username');

// Login (throws InvalidCredentialsException on failure)
$credential = $auth->login('user@example.com', 'secret123');

// Forgot -> returns a plaintext token for YOU to deliver by email/SMS
// (only the hash is stored). Returns null for an unknown identifier.
$token = $auth->forgot('user@example.com');

// Reset with the token
$auth->reset('user@example.com', $token, 'newSecret123');

Linking a subject (optional)

By default a credential stores its own identity. To attach it to your User model, resolve the subject in a before:credentials.register hook:

public function beforeHooks(): array
{
    return [
        'credentials.register' => function ($ctx) {
            $user = User::create(['email' => $ctx->get('identifier')]);
            $ctx->set('subject_type', User::class)->set('subject_id', $user->id);
        },
    ];
}

login() then returns the linked subject_type / subject_id, which your app uses to Auth::login() the user.

Hooks

Event When Notes
before:credentials.register Before creating a credential Set subject_type/subject_id to link
after:credentials.register After creation
before:credentials.login Before returning success Set allow=false to veto (e.g. locked account)
after:credentials.login On successful login
after:credentials.forgot After a reset token is issued Deliver the token here if you prefer
after:credentials.reset After a successful reset

Security notes

  • Passwords hashed with Laravel Hash (never stored plaintext; password_hash is hidden from serialization).
  • Reset tokens are random 64-char strings; only their hash is stored, and they are single-use and time-limited (reset_ttl, default 1 hour).
  • Login is timing-safe against unknown identifiers.
  • forgot-password never reveals whether an identifier exists.
  • Password delivery (reset email/SMS) is the app's responsibility.

Config

config/auth-kit-credentials.php:

'identifier_types'        => ['email', 'phone', 'username'],
'default_identifier_type' => 'email',
'lowercase_types'         => ['email', 'username'],
'min_password_length'     => 8,
'reset_ttl'               => 3600, // seconds

Developing against a local core

composer config repositories.auth-kit path ../auth-kit
composer require gusmanwidodo/auth-kit:@dev
composer install
composer test   # 18 tests

Note: composer require :@dev rewrites this composer.json to @dev. Revert the gusmanwidodo/auth-kit constraint to ^0.1 and remove any repositories block before committing/tagging a release.

License

MIT © Gusman Widodo. See LICENSE.