UNPKG

@oa2/core

Version:

A comprehensive, RFC-compliant OAuth 2.0 authorization server implementation in TypeScript

326 lines (324 loc) 13.7 kB
/** * Export a type that list the posible error coes */ type OAuth2ErrorCode = 'invalid_request' | 'unauthorized_client' | 'access_denied' | 'unsupported_response_type' | 'invalid_scope' | 'server_error' | 'temporarily_unavailable' | 'invalid_grant' | 'unsupported_grant_type'; /** * Represents an incoming OAuth2 request, abstracting away framework-specific details. * @see RFC 6749, Section 3.1 Authorization Endpoint * @see RFC 6749, Section 3.2 Token Endpoint */ interface OAuth2Request { /** The path of the request (e.g., '/token'). */ path: string; /** The HTTP method of the request (GET or POST). */ method: 'GET' | 'POST'; /** A record of request headers. */ headers: Record<string, string>; /** A record of query parameters. */ query: Record<string, string>; /** The request body, parsed as a record of any type. */ body?: Record<string, any> | string; /** A record of request cookies. */ cookies: Record<string, string>; } /** * Represents an outgoing OAuth2 response, abstracting away framework-specific details. * @see RFC 6749, Section 3.1.2 Redirection Endpoint * @see RFC 6749, Section 4.1.4 Access Token Response * @see RFC 6749, Section 5.1 Successful Response * @see RFC 6749, Section 5.2 Error Response */ interface OAuth2Response { /** The HTTP status code of the response. */ statusCode: number; /** A record of response headers. */ headers: Record<string, string>; /** The response body, which can be a record of any type. */ body: Record<string, any>; /** Optional: A URL to redirect to, if the response is a redirect. */ redirect?: string; /** A record of response cookies. */ cookies: Record<string, string>; } /** * Represents an OAuth2 client application. * @see RFC 6749, Section 2. Client Registration * @see RFC 6749, Section 2.1 Client Types * @see RFC 6749, Section 2.2 Client Identifier * @see RFC 6749, Section 2.3 Client Authentication */ interface Client { /** The unique identifier for the client. */ id: string; /** The client secret, hashed for confidential clients. */ secret: string; /** An array of registered redirect URIs for the client. */ redirectUris: string[]; /** An array of allowed OAuth2 grant types for the client. */ allowedGrants: string[]; /** An array of scopes that the client is allowed to request. */ scopes: string[]; /** Whether the client is allowed to use plain text PKCE. */ allowPlainTextPkce?: boolean; } /** * Represents an OAuth2 token (access token and optional refresh token). * @see RFC 6749, Section 1.4 Access Token * @see RFC 6749, Section 1.5 Refresh Token */ interface Token { /** The access token string. */ accessToken: string; /** The expiration date and time of the access token. */ accessTokenExpiresAt: Date; /** Optional: The refresh token string. */ refreshToken?: string; /** Optional: The expiration date and time of the refresh token. */ refreshTokenExpiresAt?: Date; /** The scope of the token. */ scope: string; /** The ID of the client associated with the token. */ clientId: string; /** The ID of the user associated with the token. */ userId: string; } /** * Represents an OAuth2 authorization code. * @see RFC 6749, Section 1.3.1 Authorization Code * @see RFC 7636, Section 4. Protocol (PKCE) */ interface AuthorizationCode { /** The authorization code string. */ code: string; /** The expiration date and time of the authorization code. */ expiresAt: Date; /** The redirect URI used in the authorization request. */ redirectUri: string; /** The scope requested during authorization. */ scope: string; /** The ID of the client associated with the authorization code. */ clientId: string; /** The ID of the user associated with the authorization code. */ userId: string; /** The PKCE code challenge. */ codeChallenge: string; /** The PKCE code challenge method (S256 or plain). */ codeChallengeMethod: 'S256' | 'plain'; } /** * Defines the contract for a storage adapter, responsible for persisting and retrieving OAuth2-related data. * This interface abstracts the underlying data storage mechanism. */ interface StorageAdapter<U extends any = any> { /** * Retrieves a client by its ID. * @param clientId The ID of the client. * @returns A Promise that resolves to the Client object or null if not found. */ getClient(clientId: string): Promise<Client | null>; /** * Saves a token (access token and/or refresh token). * @param token The Token object to save. * @returns A Promise that resolves when the token is saved. */ saveToken(token: Token): Promise<void>; /** * Retrieves an access token. * @param accessToken The access token string. * @returns A Promise that resolves to the Token object or null if not found. */ getAccessToken(accessToken: string): Promise<Token | null>; /** * Retrieves a refresh token. * @param refreshToken The refresh token string. * @returns A Promise that resolves to the Token object or null if not found. */ getRefreshToken(refreshToken: string): Promise<Token | null>; /** * Saves an authorization code. * @param code The AuthorizationCode object to save. * @returns A Promise that resolves when the authorization code is saved. */ saveAuthorizationCode(code: AuthorizationCode): Promise<void>; /** * Retrieves an authorization code. * @param code The authorization code string. * @returns A Promise that resolves to the AuthorizationCode object or null if not found. */ getAuthorizationCode(code: string): Promise<AuthorizationCode | null>; /** * Deletes an authorization code. * @param code The authorization code string to delete. * @returns A Promise that resolves when the authorization code is deleted. */ deleteAuthorizationCode(code: string): Promise<void>; /** * Revokes a token (access token or refresh token). * @param token The token string to revoke. * @returns A Promise that resolves when the token is revoked. */ revokeToken(token: string): Promise<void>; /** * Retrieves a user by their ID. * @param userId The ID of the user. * @returns A Promise that resolves to the user object or null if not found. */ getUser(userId: string): Promise<any | null>; /** * Retrieves a user by their credentials (username and password), if the credentials are invalid, it returns null. * @param username The username of the user. * @param password The password of the user. */ getUserByCredentials(username: string, password: string): Promise<any | null>; } /** * Defines the contract for an OAuth2 grant type handler. * @see RFC 6749, Section 1.3 Authorization Grant */ interface Grant { /** * The Grant type identifier (e.g., 'authorization_code', 'client_credentials'), this identifer is unique across all grants. * This is used to identify the grant type in requests. */ type: string; /** * Optional: An array of response types supported by this grant, e.g., ['code', 'token']. This is used to identify the grant type in requests * that can support the response type for the `/authorize` endpoint. */ responseTypes?: string[]; /** * Called on the `/authorize` endpoint (e.g., for `authorization_code`). */ handleAuthorization?(context: Context): Promise<OAuth2Response>; /** * Called on the `/token` endpoint (e.g., for exchanging a code). */ handleToken?(context: Context): Promise<OAuth2Response>; /** * Optional validation before token issuance (e.g., PKCE, scopes, audience). */ validate?(context: Context): Promise<void>; /** * Optional hook to resolve scopes (may throw if invalid). */ resolveScopes?(context: Context): Promise<string[]>; } /** * Parameters for token generation, providing all necessary context and data. */ interface TokenGenerationParams { /** The authenticated client */ client: Client; /** The user ID associated with the token */ userId: string; /** The scope for the token */ scope: string; /** Additional metadata that can be included in the token */ metadata?: Record<string, any>; } /** * Interface for defining a TokenStrategy, which is responsible for generating and validating tokens. * This interface provides a clean abstraction for different token implementations (JWT, opaque, etc.) */ interface TokenStrategy { /** * Generates a new access token with the specified parameters. * @param params Token generation parameters including client, user, and scope information * @param context The context containing request details and storage adapter * @returns A Promise that resolves to a Token object containing the access token */ generateAccessToken(params: TokenGenerationParams, context: Context): Promise<Token>; /** * Validates an access token and returns token information if valid. * @param accessToken The access token string to validate * @param context The context containing request details and storage adapter * @returns A Promise that resolves to a Token object if valid, or null if invalid */ validateAccessToken(accessToken: string, context: Context): Promise<Token | null>; /** * Generates a new refresh token with the specified parameters. * @param params Token generation parameters including client, user, and scope information * @param context The context containing request details and storage adapter * @returns A Promise that resolves to a Token object containing the refresh token */ generateRefreshToken(params: TokenGenerationParams, context: Context): Promise<Token>; /** * Validates a refresh token and returns token information if valid. * @param refreshToken The refresh token string to validate * @param context The context containing request details and storage adapter * @returns A Promise that resolves to a Token object if valid, or null if invalid */ validateRefreshToken(refreshToken: string, context: Context): Promise<Token | null>; /** * Optional: Generate both access and refresh tokens in a single call for efficiency. * If not implemented, will fall back to calling generateAccessToken and generateRefreshToken separately. * @param params Token generation parameters * @param context The context containing request details and storage adapter * @returns A Promise that resolves to a Token object containing both tokens */ generateTokenPair?(params: TokenGenerationParams, context: Context): Promise<Token>; } /** * Represents the context for an OAuth2 operation, containing request details, storage adapter, and authenticated client. */ interface Context { /** Server Config */ config: ServerConfig; /** The incoming OAuth2 request. */ request: OAuth2Request; /** The storage adapter for data persistence. */ storage: StorageAdapter; /** Optional: The authenticated client associated with the request. */ client?: Client; } /** * Defines the configuration options for the OAuth2 server. */ interface ServerConfig { /** The storage adapter to be used by the server. */ storage: StorageAdapter; /** The token strategy to be used by the server. If not provided, defaults to opaque token strategy. */ tokenStrategy?: TokenStrategy; /** An array of supported grant type handlers. */ grants: Grant[]; /** An array of predefined, valid scopes supported by the server. */ predefinedScopes: string[]; /** Optional: The lifetime of the access token in seconds. Defaults to 3600 (1 hour). */ accessTokenLifetime?: number; /** Optional: The lifetime of the refresh token in seconds. Defaults to 604800 (7 days). */ refreshTokenLifetime?: number; /** Optional: The lifetime of the authorization code in seconds. Defaults to 600 (10 minutes). */ authorizationCodeLifetime?: number; } /** * Defines the public interface for the OAuth2 server. * @see RFC 6749, Section 1.2 Protocol Flow */ interface OAuth2Server { /** * Handles an authorization request. * @param request The incoming OAuth2 authorization request. * @returns A Promise that resolves to an OAuth2Response. */ authorize(request: OAuth2Request): Promise<OAuth2Response>; /** * Handles a token request. * @param request The incoming OAuth2 token request. * @returns A Promise that resolves to an OAuth2Response containing the token details. */ token(request: OAuth2Request): Promise<OAuth2Response>; /** * Handles a token revocation request. * @param request The incoming OAuth2 revocation request. * @returns A Promise that resolves to an OAuth2Response with a 200 status code upon successful revocation. */ revoke(request: OAuth2Request): Promise<OAuth2Response>; /** * Handles a token introspection request. * @param request The incoming OAuth2 introspection request. * @returns A Promise that resolves to an OAuth2Response containing the token's introspection data. */ introspect(request: OAuth2Request): Promise<OAuth2Response>; } export type { AuthorizationCode, Client, Context, Grant, OAuth2ErrorCode, OAuth2Request, OAuth2Response, OAuth2Server, ServerConfig, StorageAdapter, Token, TokenGenerationParams, TokenStrategy }; //# sourceMappingURL=types.d.ts.map