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/postline
آخر نشاط في المصدر
٣ أغسطس ٢٠٢٦ في ١٩:٣٤
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٢
التفرعات
٠

خيارات التثبيت

يُحدَّد 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