import { IdentityProviderUser, IdentityProviderRole, IdentityProviderUserPermission, IdentityProviderLoginAttempt, IdentityProviderUserWithRoles } from "@kottster/common"; import { KottsterApp } from "./app"; import { Knex } from "knex"; import { Request } from "express"; /** * Supported hashing algorithms */ export declare enum HashAlgorithm { bcrypt = "bcrypt", sha256 = "sha256" } /** * JWT payload interface */ export interface JwtPayload { id: IdentityProviderUser['id']; check: string; iat?: number; exp?: number; } export declare enum IdentityProviderStrategyType { sqlite = "sqlite" } export interface IdentityProviderOptions { /** * The SQLite database file name. */ fileName: string; /** * The password hashing algorithm to use. * @default 'bcrypt' */ passwordHashAlgorithm: keyof typeof HashAlgorithm; /** * The root admin username */ rootUsername?: string; /** * The root admin password */ rootPassword?: string; /** * The root admin custom permissions */ rootCustomPermissions?: string[]; /** * The salt used to sign JWT tokens */ jwtSecretSalt?: string; } /** * Post-authentication middleware for additional processing after user authorization */ export type PostAuthMiddleware = (user: IdentityProviderUserWithRoles, request: Request) => void | Promise; /** * The identity provider */ export declare class IdentityProvider { private app; private jwtSecretSalt?; private passwordHashAlgorithm; private rootUserUsername?; private rootUserPassword?; private rootUserSalt?; private rootCustomPermissions; private db; constructor({ fileName, jwtSecretSalt, passwordHashAlgorithm, rootUsername, rootPassword, rootCustomPermissions, }: IdentityProviderOptions); get jwtSecret(): string | undefined; setApp(app: KottsterApp): void; recordLoginAttempt(attempt: Omit): Promise; getRootUserSalt(): string; updateRole(roleId: IdentityProviderRole['id'], role: Partial): Promise; deleteRole(roleId: IdentityProviderRole['id']): Promise; createUser(user: Omit, password: string): Promise; updateUser(userId: IdentityProviderUser['id'], data: Partial): Promise; /** * Update user with only non-sensitive fields */ updateUserNonSensitiveFields(userId: IdentityProviderUser['id'], data: Partial): Promise; updateUserPassword(userId: IdentityProviderUser['id'], newPassword: string, temporaryPassword?: boolean): Promise; deleteUser(userId: IdentityProviderUser['id']): Promise; getUserPermissions(userId: number | string): Promise; /** * Hash a password using the configured algorithm */ hashPassword(password: string): Promise; /** * Verify a password against a hash */ verifyPassword(password: string, hash: string): Promise; getRootUserByUsername(username: string): IdentityProviderUser | undefined; getRootUserById(userId: number | string): IdentityProviderUser | undefined; isUserRoot(userId: number | string): boolean; authenticateRootUser(username: string, password: string): Promise; /** * Authenticate a user by username/email and password * @param usernameOrEmail - Username or email to identify the user * @param password - Plain text password to check * @returns Authenticated user */ authenticateUser(usernameOrEmail: string, password: string): Promise; /** * Generate a JWT token for the root user * @param expiresIn - Token expiration in seconds (default: 24h = 86400s) * @returns JWT token string */ generateTokenForRootUser(expiresIn?: number, providedJwtSecret?: string): Promise; /** * Generate a JWT token for a user * @param usernameOrEmail - Username or email to identify the user * @param expiresIn - Token expiration in seconds (default: 24h = 86400s) * @returns JWT token string */ generateToken(userId: number | string, expiresIn?: number): Promise; /** * Verify and decode a JWT token * @param token - JWT token to verify * @returns Decoded JWT payload or null if invalid */ verifyToken(token: string): Promise; verifyTokenAndGetUser(token: string): Promise; /** * Check if a user has a specific role by role ID */ userHasRole(userId: number | string, roleId: number | string): Promise; userHasPermissions(userId: number | string, permissions: (keyof typeof IdentityProviderUserPermission | string)[]): Promise; /** * Check if a user has a specific role by role name */ userHasRoleByName(userId: number | string, roleName: string): Promise; /** * Get all roles for a specific user */ getUserRoles(userId: number | string): Promise; initialize(): Promise; private ensureTablesExist; private createUsersTable; private createRolesTable; private createUserRolesTable; private createLoginAttemptsTable; private createSchemaVersionsTable; getUserBy(field: 'id' | 'email' | 'username', value: string | number): Promise; getUserWhere(where: Record | ((qb: Knex.QueryBuilder) => void)): Promise; getUsers(): Promise; private mapUserFromDb; createRole(role: Omit): Promise; getRoleBy(field: 'id' | 'name', value: string | number): Promise; getRolesByIds(roleIds: IdentityProviderRole['id'][]): Promise; getRoles(): Promise; private mapRoleFromDb; createdLoginAttempt(attempt: Omit): Promise; getRecentFailedAttempts(identifier: string, ipAddress: string, minutes?: number): Promise; isIpBlocked(ipAddress: string, maxAttempts?: number, minutes?: number): Promise; cleanOldLoginAttempts(daysToKeep?: number): Promise; updateLastLoginAt(userId: IdentityProviderUser['id']): Promise; invalidateAllSessions(userId: IdentityProviderUser['id']): Promise; close(): Promise; getDb(): Knex; }