Skip to main content

stacks-auth

Use when implementing authentication, authorization, passkeys, TOTP/2FA, RBAC, gates, policies, session auth, token management, email verification, password resets, or rate limiting in a Stacks application. Covers the @stacksjs/auth package, config/auth.ts, app/Gates.ts, and app/Middleware/.

ソース情報

リポジトリ
stacksjs/harness
ソースの最終更新活動
2026年8月7日 21:41
検出された SKILL.md の言語
英語
スター
1
フォーク
0

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
stacks-auth
description
Use when implementing authentication, authorization, passkeys, TOTP/2FA, RBAC, gates, policies, session auth, token management, email verification, password resets, or rate limiting in a Stacks application. Covers the @stacksjs/auth package, config/auth.ts, app/Gates.ts, and app/Middleware/.
license
MIT
compatibility
Bun >= 1.3.0, TypeScript
allowed-tools
Read Edit Write Bash Grep Glob
# Stacks Authentication & Authorization The `@stacksjs/auth` package provides comprehensive authentication and authorization for Stacks applications, built on `@stacksjs/ts-auth`. ## Key Paths - Core package source: `storage/framework/core/auth/src/` - Configuration: `config/auth.ts` - Security config: `config/security.ts` - Hashing config: `config/hashing.ts` - Application gates: `app/Gates.ts` - Application middleware: `app/Middleware/` - Middleware aliases: `app/Middleware.ts` - Auth types: `storage/framework/core/types/src/auth.ts` ## Source Files ``` auth/src/ ├── index.ts # All re-exports ├── authentication.ts # Auth class - core auth logic ├── authenticator.ts # 2FA and personal access client ├── client.ts # Client re-exports ├── middleware.ts # Auth middleware handler ├── rate-limiter.ts # RateLimiter class (5 attempts, 15min lockout) ├── passkey.ts # WebAuthn/Passkey support ├── password/reset.ts # Password reset flow ├── register.ts # User registration ├── user.ts # Auth user helpers ├── tokens.ts # Token CRUD, scopes, refresh tokens, OAuth clients ├── gate.ts # Authorization gates & policies ├── policy.ts # BasePolicy class + discovery ├── authorizable.ts # User authorization mixin ├── rbac.ts # Full RBAC system ├── email-verification.ts # Email verification flow └── session-auth.ts # Session-based SPA auth ``` ## Auth Class (authentication.ts) — Static Methods ### Login & Authentication - `Auth.attempt(credentials: AuthCredentials): Promise<boolean>` — validate credentials without creating token - `Auth.validate(credentials: AuthCredentials): Promise<boolean>` — alias for attempt - `Auth.login(credentials: AuthCredentials, options?: TokenCreateOptions): Promise<{ user, token } | null>` — login and create token - `Auth.loginUsingId(userId: number, options?: TokenCreateOptions): Promise<{ user, token } | null>` — login by user ID - `Auth.logout(): Promise<void>` — revoke current token - `Auth.once(credentials: AuthCredentials): Promise<boolean>` — one-time auth without token - `Auth.requestToken(credentials, clientId, clientSecret): Promise<{ token } | null>` — OAuth token request ### User State - `Auth.user(): Promise<UserModel | undefined>` — get authenticated user from bearer token - `Auth.check(): Promise<boolean>` — is user authenticated? - `Auth.guest(): Promise<boolean>` — is user a guest? - `Auth.id(): Promise<number | undefined>` — get authenticated user ID - `Auth.setUser(user: UserModel): void` — manually set user ### Token Creation - `Auth.createTokenForUser(user, options?: TokenCreateOptions): Promise<NewAccessToken>` - `Auth.createToken(user, name?, abilities?): Promise<AuthToken>` ### Token Validation - `Auth.validateToken(token: string): Promise<boolean>` — validate bearer token - `Auth.getUserFromToken(token: string): Promise<UserModel | undefined>` - `Auth.currentAccessToken(): Promise<PersonalAccessToken | undefined>` ### Token Abilities (Scopes) - `Auth.tokenCan(ability: string): Promise<boolean>` - `Auth.tokenCant(ability: string): Promise<boolean>` - `Auth.tokenAbilities(): Promise<string[]>` - `Auth.tokenCanAll(abilities: string[]): Promise<boolean>` - `Auth.tokenCanAny(abilities: string[]): Promise<boolean>` ### Token Management - `Auth.tokens(userId?: number): Promise<PersonalAccessToken[]>` - `Auth.revokeToken(token: string): Promise<void>` - `Auth.revokeTokenById(tokenId: number): Promise<void>` - `Auth.revokeAllTokens(userId?: number): Promise<void>` - `Auth.revokeOtherTokens(userId?: number): Promise<void>` - `Auth.pruneExpiredTokens(): Promise<number>` - `Auth.pruneRevokedTokens(): Promise<number>` - `Auth.rotateToken(oldToken: string): Promise<AuthToken | null>` - `Auth.findToken(tokenId: number): Promise<PersonalAccessToken | null>` ### Utility - `Auth.guard(name?: string): typeof Auth` — select guard (returns self) - `Auth.viaRemember(): boolean` — always false currently - `Auth.clearState(): void` — clear cached user/token ## Token System (tokens.ts) ### Access Tokens - `tokens(userId: number): Promise<AccessToken[]>` - `findToken(plainTextToken: string): Promise<AccessToken | null>` - `currentAccessToken(): Promise<AccessToken | null>` - `createToken(userId, name?, scopes?, options?): Promise<PersonalAccessTokenResult>` - Options: `{ expiresInMinutes?, withRefreshToken?, refreshExpiresInDays? }` ### Refresh Tokens - `refreshToken(refreshTokenPlain, options?): Promise<RefreshTokenResult>` - `validateRefreshToken(refreshTokenPlain): Promise<boolean>` - `revokeRefreshToken(refreshTokenPlain): Promise<void>` - `revokeAllRefreshTokens(userId): Promise<void>` - `deleteExpiredRefreshTokens(): Promise<number>` - `deleteRevokedRefreshTokens(daysOld?): Promise<number>` ### Token Revocation - `revokeToken(plainTextToken): Promise<void>` - `revokeTokenById(tokenId): Promise<void>` - `revokeAllTokens(userId): Promise<void>` - `revokeOtherTokens(userId): Promise<void>` - `deleteExpiredTokens(): Promise<number>` - `deleteRevokedTokens(daysOld?): Promise<number>` ### Token Scopes - `tokenCan(scope): Promise<boolean>` - `tokenCant(scope): Promise<boolean>` - `tokenCanAll(scopes): Promise<boolean>` - `tokenCanAny(scopes): Promise<boolean>` - `tokenAbilities(): Promise<string[]>` - `parseScopes(scopes: string | string[] | null | undefined): TokenScopes` ### OAuth Clients - `clients(userId): Promise<OAuthClient[]>` - `findClient(clientId): Promise<OAuthClient | null>` - `createClient(options: CreateClientOptions): Promise<CreateClientResult>` - `revokeClient(clientId): Promise<void>` ## Two-Factor Authentication (authenticator.ts) - `generateTwoFactorSecret(): string` - `generateTwoFactorToken(secret: Secret): Promise<Token>` - `verifyTwoFactorCode(token: Token, secret: Secret): Promise<boolean>` - `generateTwoFactorUri(user?, service?, secret?): string` - `createPersonalAccessClient(): Promise<Result<string, never>>` ### Re-exported from @stacksjs/ts-auth - `generateTOTP`, `verifyTOTP`, `generateTOTPSecret`, `totpKeyUri` ## Authorization Gates (gate.ts) ### Gate Functions - `define<T>(ability: string, callback: GateCallback<T>): void` - `policy(model: string | { name }, policyClass: new () => Policy): void` - `before(callback): void` — run before any gate check - `after(callback): void` — run after any gate check - `allows(ability, user, ...args): Promise<boolean>` - `denies(ability, user, ...args): Promise<boolean>` - `can(ability, user, ...args): Promise<boolean>` - `cannot(ability, user, ...args): Promise<boolean>` - `any(abilities[], user, ...args): Promise<boolean>` - `all(abilities[], user, ...args): Promise<boolean>` - `none(abilities[], user, ...args): Promise<boolean>` - `authorize(ability, user, ...args): Promise<AuthorizationResponse>` — throws on deny - `inspect(ability, user, ...args): Promise<AuthorizationResponse>` — never throws - `has(ability): boolean` - `hasPolicy(model): boolean` - `abilities(): string[]` - `getPolicyFor<T>(model: T): Policy<T> | null` - `flush(): void` — clear all gates ### Gate Facade — `Gate.define()`, `Gate.can()`, etc ### AuthorizationResponse Class - `static allow(message?): AuthorizationResponse` - `static deny(message?, code?): AuthorizationResponse` - `allowed(): boolean`, `denied(): boolean` - `authorize(): void` — throws AuthorizationException if denied ### Policy Interface Methods: `before?`, `viewAny?`, `view?`, `create?`, `update?`, `delete?`, `restore?`, `forceDelete?` ### BasePolicy Abstract Class Protected helpers: `allow(message?)`, `deny(message?, code?)`, `denyIf(condition)`, `denyUnless(condition)`, `allowIf(condition)` ## RBAC System (rbac.ts) ### Role Management - `Rbac.createRole(name, guardName?, description?): Promise<RoleRecord>` - `Rbac.findRole(name, guardName?): Promise<RoleRecord | null>` - `Rbac.deleteRole(name, guardName?): Promise<void>` - `Rbac.getAllRoles(guardName?): Promise<RoleRecord[]>` ### Permission Management - `Rbac.createPermission(name, guardName?, description?): Promise<PermissionRecord>` - `Rbac.findPermission(name, guardName?): Promise<PermissionRecord | null>` - `Rbac.deletePermission(name, guardName?): Promise<void>` - `Rbac.getAllPermissions(guardName?): Promise<PermissionRecord[]>` ### User-Role Operations - `Rbac.getUserRoles(user): Promise<RoleRecord[]>` - `Rbac.assignRole(user, roleName, guardName?): Promise<void>` - `Rbac.removeRole(user, roleName, guardName?): Promise<void>` - `Rbac.removeAllRoles(user): Promise<void>` - `Rbac.syncRoles(user, roleNames[], guardName?): Promise<void>` - replaces assignments for that guard and preserves roles from other guards - `Rbac.hasRole(user, roleName, guardName?): Promise<boolean>` - `Rbac.hasAnyRole(user, roleNames[], guardName?): Promise<boolean>` - `Rbac.hasAllRoles(user, roleNames[], guardName?): Promise<boolean>` ### User-Permission Operations - `Rbac.getUserPermissions(user): Promise<PermissionRecord[]>` - `Rbac.givePermission(user, permissionName, guardName?): Promise<void>` - `Rbac.revokePermission(user, permissionName, guardName?): Promise<void>` - `Rbac.revokeAllPermissions(user): Promise<void>` - `Rbac.syncPermissions(user, permissionNames[], guardName?): Promise<void>` - `Rbac.hasPermission(user, permissionName, guardName?): Promise<boolean>` - `Rbac.hasAnyPermission(user, permissionNames[], guardName?): Promise<boolean>` - `Rbac.hasAllPermissions(user, permissionNames[], guardName?): Promise<boolean>` ### Role-Permission Operations - `Rbac.getRolePermissions(roleId): Promise<PermissionRecord[]>` - `Rbac.givePermissionToRole(roleName, permissionName, guardName?): Promise<void>` - `Rbac.revokePermissionFromRole(roleName, permissionName, guardName?): Promise<void>` - `Rbac.syncRolePermissions(roleName, permissionNames[], guardName?): Promise<void>` ### withRbac Mixin `withRbac(user)` — adds `hasRole()`, `hasPermission()`, `assignRole()`, `givePermission()`, etc. to any user object ### RBAC Types ```typescript interface RoleRecord { id, name, guard_name, description?, created_at?, updated_at? } interface PermissionRecord { id, name, guard_name, description?, created_at?, updated_at? } interface RbacStore { findRoleByName, createRole, deleteRole, getAllRoles, findPermissionByName, createPermission, ... } ``` ## Session Auth (session-auth.ts) - `SessionAuth.login(email, password): Promise<{ user, sessionId }>` - `SessionAuth.logout(sessionId): void` - `SessionAuth.user(sessionId): Promise<UserModel | undefined>` - `SessionAuth.check(sessionId): boolean` - `SessionAuth.refresh(sessionId, ttlMs?): boolean` Internal: in-memory Map with 10k session limit, 5-minute eviction interval, timing-safe password comparison with dummy bcrypt hash. ## Email Verification (email-verification.ts) - `EmailVerification.isVerified(user): boolean` - `EmailVerification.send(user): Promise<void>` - `EmailVerification.verify(userId, token): Promise<EmailVerificationResult>` - `EmailVerification.resend(user): Promise<EmailVerificationResult>` ## Password Reset (password/reset.ts) ```typescript const actions = passwordResets(email) await actions.sendEmail() const valid = await actions.verifyToken(token)
GitHubで見る
この SKILL.md は非常に大きいため、SkillsMP では最初のセクションだけを表示しています。 GitHubで見る