@withstudiocms/auth-kit
Version:
Utilities for managing authentication
139 lines (138 loc) • 10.6 kB
TypeScript
import { Effect } from '@withstudiocms/effect';
import { AuthKitOptions, PasswordModConfigFinal, type RawAuthKitConfig } from './config.js';
export { Password } from './modules/password.js';
/**
* Creates a scrypt password hashing utility using the provided scrypt configuration.
*
* @param scrypt - The scrypt configuration object from `PasswordModConfigFinal`.
* @returns An Effect that provides an object with a `run` method for performing scrypt operations.
*/
export declare const makeScrypt: (config: PasswordModConfigFinal) => Effect.Effect.AsEffect<Effect.Effect<Effect.Effect<{
run: (password: import("crypto").BinaryLike) => Effect.Effect<Buffer<ArrayBufferLike>, import("@withstudiocms/effect/scrypt").ScryptError, never>;
}, never, never>, Error, never>>;
declare const AuthKit_base: Effect.Service.Class<AuthKit, "@withstudiocms/AuthKit", {
readonly effect: Effect.Effect<{
readonly Encryption: Effect.Effect<{
readonly encrypt: (data: Uint8Array<ArrayBufferLike>) => Effect.Effect.AsEffect<Effect.Effect<Uint8Array<ArrayBufferLike>, import("./errors.js").EncryptionError, never>>;
readonly encryptToString: (data: string) => Effect.Effect<Uint8Array<ArrayBufferLike>, import("./errors.js").EncryptionError, never>;
readonly decrypt: (data: Uint8Array<ArrayBufferLike>) => Effect.Effect.AsEffect<Effect.Effect<Uint8Array<ArrayBufferLike>, import("./errors.js").DecryptionError, never>>;
readonly decryptToString: (data: Uint8Array<ArrayBufferLike>) => Effect.Effect<string, import("./errors.js").DecryptionError, never>;
}, import("./errors.js").EncryptionError, never>;
readonly Password: Effect.Effect<{
readonly hashPassword: (password: string, _salt?: string | undefined) => Effect.Effect<string, import("@withstudiocms/effect/scrypt").ScryptError, never>;
readonly verifyPasswordHash: (hash: string, password: string) => Effect.Effect<boolean, import("@withstudiocms/effect/scrypt").ScryptError | import("./errors.js").PasswordError, never>;
readonly verifyPasswordStrength: (pass: string) => Effect.Effect<string | true, import("./errors.js").PasswordError | import("./errors.js").CheckIfUnsafeError | import("@effect/platform/HttpClientError").ResponseError, never>;
}, never, never>;
readonly Session: Effect.Effect<{
readonly generateSessionToken: () => Effect.Effect.AsEffect<Effect.Effect<string, import("./errors.js").SessionError, never>>;
readonly createSession: (token: string, userId: string) => Effect.Effect<import("./types.js").UserSession, import("./errors.js").SessionError, never>;
readonly validateSessionToken: (token: string) => Effect.Effect<import("./types.js").SessionValidationResult, import("./errors.js").SessionError, never>;
readonly invalidateSession: (sessionId: string) => Effect.Effect.AsEffect<Effect.Effect<void, import("./errors.js").SessionError, never>>;
readonly setSessionTokenCookie: (context: import("astro").APIContext<Record<string, any>, Record<string, string | undefined>> | import("astro").AstroGlobal<Record<string, any>, import("astro/runtime/server/index.js").AstroComponentFactory, Record<string, string | undefined>>, token: string, expiresAt: Date, secure?: boolean | undefined) => Effect.Effect.AsEffect<Effect.Effect<void, import("./errors.js").SessionError, never>>;
readonly deleteSessionTokenCookie: (context: import("astro").APIContext<Record<string, any>, Record<string, string | undefined>> | import("astro").AstroGlobal<Record<string, any>, import("astro/runtime/server/index.js").AstroComponentFactory, Record<string, string | undefined>>, secure?: boolean | undefined) => Effect.Effect.AsEffect<Effect.Effect<void, import("./errors.js").SessionError, never>>;
readonly setOAuthSessionTokenCookie: (context: import("astro").APIContext<Record<string, any>, Record<string, string | undefined>> | import("astro").AstroGlobal<Record<string, any>, import("astro/runtime/server/index.js").AstroComponentFactory, Record<string, string | undefined>>, key: string, value: string, secure?: boolean | undefined) => Effect.Effect.AsEffect<Effect.Effect<void, import("./errors.js").SessionError, never>>;
readonly createUserSession: (userId: string, context: import("astro").APIContext<Record<string, any>, Record<string, string | undefined>> | import("astro").AstroGlobal<Record<string, any>, import("astro/runtime/server/index.js").AstroComponentFactory, Record<string, string | undefined>>, secure?: boolean | undefined) => Effect.Effect<void, import("./errors.js").SessionError, never>;
}, import("./errors.js").SessionError, never>;
readonly User: Effect.Effect<{
readonly verifyUsernameInput: (username: string) => Effect.Effect<string | true, import("./errors.js").CheckIfUnsafeError | import("./errors.js").UserError, never>;
readonly createUserAvatar: (email: string) => Effect.Effect.AsEffect<Effect.Effect<string, import("./errors.js").UserError, never>>;
readonly createLocalUser: (name: string, username: string, email: string, password: string) => Effect.Effect<{
name: string;
username: string;
id: string;
url: string | null;
email: string | null;
avatar: string | null;
password: string | null;
updatedAt: Date | null;
createdAt: Date | null;
emailVerified: boolean;
notifications: string | null;
}, import("@withstudiocms/effect/scrypt").ScryptError | import("./errors.js").UserError, never>;
readonly createOAuthUser: (data: import("./types.js").UserData, oAuthFields: {
provider: string;
providerUserId: string;
}) => Effect.Effect<{
name: string;
username: string;
id: string;
url: string | null;
email: string | null;
avatar: string | null;
password: string | null;
updatedAt: Date | null;
createdAt: Date | null;
emailVerified: boolean;
notifications: string | null;
}, import("./errors.js").UserError, never>;
readonly updateUserPassword: (userId: string, password: string) => Effect.Effect<{
name: string;
username: string;
id: string;
url: string | null;
email: string | null;
avatar: string | null;
password: string | null;
updatedAt: Date | null;
createdAt: Date | null;
emailVerified: boolean;
notifications: string | null;
}, import("@withstudiocms/effect/scrypt").ScryptError | import("./errors.js").UserError, never>;
readonly getUserPasswordHash: (userId: string) => Effect.Effect<string, import("./errors.js").UserError, never>;
readonly getUserFromEmail: (email: string) => Effect.Effect.AsEffect<Effect.Effect<import("./types.js").CombinedUserData | null | undefined, import("./errors.js").UserError, never>>;
readonly getUserData: (context: import("astro").APIContext<Record<string, any>, Record<string, string | undefined>> | import("astro").AstroGlobal<Record<string, any>, import("astro/runtime/server/index.js").AstroComponentFactory, Record<string, string | undefined>>) => Effect.Effect<import("./types.js").UserSessionData, import("./errors.js").SessionError | import("./errors.js").UserError, never>;
readonly getUserPermissionLevel: (userData: import("./types.js").UserSessionData | import("./types.js").CombinedUserData | null) => Effect.Effect<import("./types.js").UserPermissionLevel, import("./errors.js").UserError, never>;
readonly isUserAllowed: (userData: import("./types.js").UserSessionData | import("./types.js").CombinedUserData | null, requiredPerms: "owner" | "admin" | "editor" | "visitor" | "unknown") => Effect.Effect<boolean, import("./errors.js").UserError, never>;
}, import("./errors.js").SessionError | import("./errors.js").UserError, never>;
}, Error, AuthKitOptions>;
}>;
/**
* The `AuthKit` service provides a collection of authentication utilities for use within the
* @withstudiocms ecosystem. It exposes encryption, password management, session management,
* and user management utilities, all configured via dependency injection.
*
* @remarks
* This service is built on top of the Effect system, allowing for composable and testable
* authentication logic. Each utility is wrapped with tracing spans for observability.
*
* @example
* ```typescript
* const authKit = AuthKit.makeConfig({
* CMS_ENCRYPTION_KEY: 'secret-key',
* session: ...,
* userTools: ...
* });
* ```
*
* @property Encryption - Provides encryption and decryption utilities using the configured key.
* @property Password - Utilities for password hashing and verification using Scrypt.
* @property Session - Session management utilities for handling user sessions.
* @property User - User management utilities, including authentication and user lookup.
*
* @method static makeConfig
* Creates a live configuration for the AuthKit service using the provided raw configuration.
*
* @see AuthKitOptions
* @see _Scrypt
* @see _Encryption
* @see _Password
* @see _Session
* @see _User
*/
export declare class AuthKit extends AuthKit_base {
/**
* Creates a live instance of `AuthKitOptions` using the provided raw configuration.
*
* @param CMS_ENCRYPTION_KEY - The encryption key used for cryptographic operations.
* @param session - session configuration overrides.
* @param userTools - Tools or utilities related to user management.
* @returns A Layer that provides the configured `AuthKitOptions`.
*
* @remarks
* - Scrypt parameters (`N`, `r`, `p`) are read from environment variables (`SCRYPT_N`, `SCRYPT_R`, `SCRYPT_P`),
* with sensible defaults and minimum values enforced for security.
* - The session configuration merges defaults with any provided overrides.
* - The returned Layer can be used for dependency injection in the application.
*/
static makeConfig: (config: RawAuthKitConfig) => import("effect/Layer").Layer<AuthKitOptions, never, never>;
}