import { User } from "../../types"; import { ArkosRequest, ArkosRequestHandler } from "../../types"; import { AuthJwtPayload, AccessAction, AccessControlConfig, AuthenticationControlConfig, DetailedAccessControlRule } from "../../types/auth"; import { MsDuration } from "./utils/helpers/auth.controller.helpers"; import { CookieOptions } from "express"; import { ArkosSocket } from "../../components/arkos-gateway/types"; /** * Handles various authentication-related tasks such as JWT signing, password hashing, and verifying user credentials. */ export declare class AuthService { /** * Object containing a combination of actions per resource, tracked by each set of calls of `authService.handleAccessControl`, this can be accessed through the `authService` object or through the endpoint */ actionsPerResource: Record>; /** * Signs a JWT token for the user. * * @param {number | string} id - The unique identifier of the user to generate the token for. * @param {string | number} [expiresIn] - The expiration time for the token. Defaults to environment variable `JWT_EXPIRES_IN`. * @param {string} [secret] - The secret key used to sign the token. Defaults to environment variable `JWT_SECRET`. * @returns {string} The signed JWT token. */ signJwtToken(id: number | string, expiresIn?: MsDuration | number, secret?: string): string; /** * Retrieves cookie configuration options for JWT authentication. * * Merges configuration from multiple sources in order of precedence: * 1. Arkos configuration file * 2. Environment variables * 3. Request properties (for secure flag) * 4. Default fallback values * * @param req - ArkosRequest object used to determine if the connection is secure * @returns Cookie options object with expires, httpOnly, secure, and sameSite properties * * @example * ```typescript * const cookieOptions = authService.getJwtCookieOptions(req); * res.cookie('jwt', token, cookieOptions); * ``` */ getJwtCookieOptions(req: ArkosRequest): CookieOptions; /** * Is used by default internally by Arkos under `BaseService` class to check if the password is already hashed. * * This was just added to prevent unwanted errors when someone just forgets that the `BaseService` class will automatically hash the password field using `authService.hashPassword` by default. * * So now before `BaseService` hashes it will test it. * * * @param password The password to be tested if is hashed * @returns */ isPasswordHashed(password: string): boolean; /** * Compares a candidate password with the stored user password to check if they match. * * @param {string} candidatePassword - The password provided by the user during login. * @param {string} userPassword - The password stored in the database. * @returns {Promise} Returns true if the passwords match, otherwise false. */ isCorrectPassword(candidatePassword: string, userPassword: string): Promise; /** * Hashes a plain text password using bcrypt. * * @param {string} password - The password to be hashed. * @returns {Promise} Returns the hashed password. */ hashPassword(password: string): Promise; /** * Checks if a password is strong, requiring uppercase, lowercase, and numeric characters as the default. * * **NB**: You must pay attention when using custom validation with zod or class-validator, try to use the same regex always. * * **Note**: You can define it when calling arkos.init() * ```ts * arkos.init({ * authentication: { * passwordValidation:{ regex: /your-desired-regex/, message: 'password must contain...'} * } * }) * ``` * * @param {string} password - The password to check. * @returns {boolean} Returns true if the password meets the strength criteria, otherwise false. */ isPasswordStrong(password: string): boolean; /** * Checks if a user has changed their password after the JWT was issued. * * @param {User} user - The user object containing the passwordChangedAt field. * @param {number} JWTTimestamp - The timestamp when the JWT was issued. * @returns {boolean} Returns true if the user changed their password after the JWT was issued, otherwise false. */ userChangedPasswordAfter(user: User, JWTTimestamp: number): boolean; /** * Verifies the authenticity of a JWT token. * * @param {string} token - The JWT token to verify. * @param {string} [secret] - The secret key used to verify the token. Defaults to environment variable `JWT_SECRET`. * @returns {Promise} Returns the decoded JWT payload if the token is valid. * @throws {Error} Throws an error if the token is invalid or expired. */ verifyJwtToken(token: string, secret?: string): Promise; private isWildcardAccess; private isRoleList; private isAccessRules; private normalizeRuleToRoles; private resolveAuthorizedRoles; /** * Checks if a user has permission for a specific action using static access control rules. * Validates user roles against predefined access control configuration. * * @param user - The user object containing role or roles field * @param action - The action being performed * @param accessControl - Access control configuration (array of roles or object with action-role mappings) * @returns True if user has permission, false otherwise * @throws Error if user doesn't have role/roles field */ checkStaticAccessControl(user: User, action: string, accessControl: AccessControlConfig): boolean; /** * Checks if a user has permission for a specific action and resource using dynamic access control. * Queries the database to verify user's role permissions. * * @param userId - The unique identifier of the user * @param action - The action being performed * @param resource - The resource being accessed * @returns Promise resolving to true if user has permission, false otherwise */ checkDynamicAccessControl(userId: string, action: string, resource: string): Promise; /** * Middleware function to handle access control based on user roles and permissions. * * @param {AccessAction} action - The action being performed (e.g., create, update, delete, view). * @param {string} resource - The resource name that the action is being performed on (e.g., "User", "Post"). * @param {AccessControlConfig} accessControl - The access control configuration. * @returns {ArkosRequestHandler} The middleware function that checks if the user has permission to perform the action. * * @deprecated Will be removed on v2.0, use AuthService.authorize instead */ handleAccessControl(action: AccessAction, resource: string, accessControl?: AccessControlConfig): ArkosRequestHandler; private extractRequestToken; private extractSocketToken; validateDecodedUser(decoded: AuthJwtPayload, action?: "logout" | "default"): Promise; /** * Processes the cookies or authoriation token and returns the user. * * @param ctx | socket * @returns {Promise} - if authentication is turned off in arkosConfig it returns null * @throws {AppError} Throws an error if the token is invalid or the user is not logged in. */ getAuthenticatedUser(ctx: ArkosRequest | ArkosSocket, action?: "logout" | "default"): Promise; /** * Middleware to authenticate the request by extracting and verifying the JWT token and setting `req.user`. * * Runs `authentication.hooks.authenticate` before/after the authentication logic. * * Hook execution flow: * - `before` hooks run first — call `ctx.skip()` to bypass core logic and jump to `after` hooks, * call `ctx.next()` to stop the chain early, or return without calling anything to continue. * - Core logic runs — extracts and verifies the JWT token, sets `req.user`. * - `after` hooks run — call `ctx.next(err)` to abort or return without calling anything to continue. * - `onError` hooks run if core logic throws — call `ctx.skip()` to suppress the error and jump to * `after` hooks, or call `ctx.next(err)` to forward it to the global error handler. * * On custom routes, hooks defined in `arkosConfig` still apply since they are baked into this method. * * @example * ```ts * // custom route - hooks still run * router.get("/custom", authService.authenticate, handler); * ``` * * @example * ```ts * // skip built-in auth from a before hook * before: (ctx) => { * ctx.req.user = myCustomAuth(ctx.req); * ctx.skip(); * } * ``` * * @see {@link https://www.arkosjs.com/docs/core-concepts/authentication/hooks} */ authenticate: any; /** * Middleware to authorize the authenticated user for a given action on a resource. * * Runs `authentication.hooks.authorize` before/after the authorization logic. * * Hook execution flow: * - `before` hooks run first — call `ctx.skip()` to bypass core logic and jump to `after` hooks, * call `ctx.next()` to stop the chain early, or return without calling anything to continue. * - Core logic runs — checks user role/permissions against the access control rules. * - `after` hooks run — call `ctx.next(err)` to abort or return without calling anything to continue. * - `onError` hooks run if authorization fails — call `ctx.skip()` to suppress the error and jump to * `after` hooks, or call `ctx.next(err)` to forward it to the global error handler. * * @param resource - The resource being accessed, in kebabCase (e.g. `"product"`, `"cart-item"`) * @param action - The action being performed (e.g. `"View"`, `"Create"`, `"Delete"`) * @param rule - Access control rules for this action. Accepts a role list, a wildcard, or a `DetailedAccessControlRule`. * * @example * ```ts * router.delete("/products/:id", * authService.authenticate, * authService.authorize("product", "Delete", ["admin"]), * handler * ); * ``` * * @example * ```ts * // skip built-in authorization from a before hook * before: (ctx) => { * ctx.req.user.role = myCustomRoleResolver(ctx.req); * ctx.skip(); * } * ``` * * @see {@link https://www.arkosjs.com/docs/core-concepts/authentication/hooks#authorize} * @since v1.6.0-beta */ authorize(action: AccessAction, resource: string, rule?: string[] | DetailedAccessControlRule | "*"): ArkosRequestHandler; /** * Handles authentication control by checking the `authenticationControl` configuration in the `authConfigs`. * * @param {ControllerActions} action - The action being performed (e.g., create, update, delete, view). * @param {AuthenticationControlConfig} authenticationControl - The authentication configuration object. * @returns {ArkosRequestHandler} The middleware function that checks if authentication is required. * * @deprecated Will be removed on v2.0, use AuthService.authenticate instead */ handleAuthenticationControl(action: AccessAction, authenticationControl?: AuthenticationControlConfig | undefined): ArkosRequestHandler; /** * Creates a permission checker function for a specific action and resource. * * PS: This method should be called during application initialization to build permission validators. * * @see {@link https://www.arkosjs.com/docs/advanced-guide/fine-grained-access-control} * * @param action - The action to check permission for (e.g., 'View', 'Create', 'Delete') * @param resource - The resource being accessed, must be in kebabCase (e.g., 'user', 'cart-item', 'order') * @param accessControl - Access control rules (required for static authentication mode), and it is automatically loaded for known modules such as all prisma models, auth and file-upload. * @returns A function that takes a user object and returns a boolean indicating permission status * * @example * ```typescript * const hasViewProductPermission = await authService.permission('View', 'product'); * * // Later in handler: * const canAccess = await hasViewProductPermission(user); * if (canAccess) { * // User has permission * } * ``` */ permission(action: string, resource: string, accessControl?: AccessControlConfig): (user: User | undefined) => Promise; } /** * Handles various authentication-related tasks such as JWT signing, password hashing, and verifying user credentials. */ declare const authService: AuthService; export default authService;