feat(oidc): feat(oidc): add OIDC provider (OidcManager, endpoints, and interfaces)
This commit is contained in:
@@ -0,0 +1,267 @@
|
||||
/**
|
||||
* OIDC (OpenID Connect) data interfaces for third-party client support
|
||||
*/
|
||||
|
||||
/**
|
||||
* Supported OIDC scopes
|
||||
*/
|
||||
export type TOidcScope = 'openid' | 'profile' | 'email' | 'organizations' | 'roles';
|
||||
|
||||
/**
|
||||
* Authorization code for OAuth 2.0 authorization code flow
|
||||
*/
|
||||
export interface IAuthorizationCode {
|
||||
/** The authorization code string */
|
||||
code: string;
|
||||
/** OAuth client ID */
|
||||
clientId: string;
|
||||
/** User ID who authorized */
|
||||
userId: string;
|
||||
/** Scopes granted */
|
||||
scopes: TOidcScope[];
|
||||
/** Redirect URI used in authorization request */
|
||||
redirectUri: string;
|
||||
/** PKCE code challenge (S256 hashed) */
|
||||
codeChallenge?: string;
|
||||
/** PKCE code challenge method */
|
||||
codeChallengeMethod?: 'S256';
|
||||
/** Nonce from authorization request (for ID token) */
|
||||
nonce?: string;
|
||||
/** Expiration timestamp (10 minutes from creation) */
|
||||
expiresAt: number;
|
||||
/** Whether the code has been used (single-use) */
|
||||
used: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* OIDC Access Token (opaque or JWT)
|
||||
*/
|
||||
export interface IOidcAccessToken {
|
||||
/** Token identifier */
|
||||
id: string;
|
||||
/** The access token string (or hash for storage) */
|
||||
tokenHash: string;
|
||||
/** OAuth client ID */
|
||||
clientId: string;
|
||||
/** User ID */
|
||||
userId: string;
|
||||
/** Granted scopes */
|
||||
scopes: TOidcScope[];
|
||||
/** Expiration timestamp */
|
||||
expiresAt: number;
|
||||
/** Creation timestamp */
|
||||
issuedAt: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* OIDC Refresh Token
|
||||
*/
|
||||
export interface IOidcRefreshToken {
|
||||
/** Token identifier */
|
||||
id: string;
|
||||
/** The refresh token string (or hash for storage) */
|
||||
tokenHash: string;
|
||||
/** OAuth client ID */
|
||||
clientId: string;
|
||||
/** User ID */
|
||||
userId: string;
|
||||
/** Granted scopes */
|
||||
scopes: TOidcScope[];
|
||||
/** Expiration timestamp */
|
||||
expiresAt: number;
|
||||
/** Creation timestamp */
|
||||
issuedAt: number;
|
||||
/** Whether the token has been revoked */
|
||||
revoked: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* User consent record for an OAuth client
|
||||
*/
|
||||
export interface IUserConsent {
|
||||
/** Unique identifier */
|
||||
id: string;
|
||||
/** User who gave consent */
|
||||
userId: string;
|
||||
/** OAuth client ID */
|
||||
clientId: string;
|
||||
/** Scopes the user consented to */
|
||||
scopes: TOidcScope[];
|
||||
/** When consent was granted */
|
||||
grantedAt: number;
|
||||
/** When consent was last updated */
|
||||
updatedAt: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* OIDC Discovery Document (OpenID Provider Configuration)
|
||||
*/
|
||||
export interface IOidcDiscoveryDocument {
|
||||
issuer: string;
|
||||
authorization_endpoint: string;
|
||||
token_endpoint: string;
|
||||
userinfo_endpoint: string;
|
||||
jwks_uri: string;
|
||||
revocation_endpoint: string;
|
||||
scopes_supported: TOidcScope[];
|
||||
response_types_supported: string[];
|
||||
grant_types_supported: string[];
|
||||
subject_types_supported: string[];
|
||||
id_token_signing_alg_values_supported: string[];
|
||||
token_endpoint_auth_methods_supported: string[];
|
||||
code_challenge_methods_supported: string[];
|
||||
claims_supported: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON Web Key Set (JWKS) response
|
||||
*/
|
||||
export interface IJwks {
|
||||
keys: IJwk[];
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON Web Key (RSA public key)
|
||||
*/
|
||||
export interface IJwk {
|
||||
kty: 'RSA';
|
||||
use: 'sig';
|
||||
alg: 'RS256';
|
||||
kid: string;
|
||||
n: string; // RSA modulus (base64url encoded)
|
||||
e: string; // RSA exponent (base64url encoded)
|
||||
}
|
||||
|
||||
/**
|
||||
* ID Token claims (JWT payload)
|
||||
*/
|
||||
export interface IIdTokenClaims {
|
||||
/** Issuer (idp.global URL) */
|
||||
iss: string;
|
||||
/** Subject (user ID) */
|
||||
sub: string;
|
||||
/** Audience (client ID) */
|
||||
aud: string;
|
||||
/** Expiration time (Unix timestamp) */
|
||||
exp: number;
|
||||
/** Issued at (Unix timestamp) */
|
||||
iat: number;
|
||||
/** Authentication time (Unix timestamp) */
|
||||
auth_time?: number;
|
||||
/** Nonce (if provided in authorization request) */
|
||||
nonce?: string;
|
||||
/** Access token hash (for hybrid flows) */
|
||||
at_hash?: string;
|
||||
|
||||
// Profile scope claims
|
||||
name?: string;
|
||||
preferred_username?: string;
|
||||
picture?: string;
|
||||
|
||||
// Email scope claims
|
||||
email?: string;
|
||||
email_verified?: boolean;
|
||||
|
||||
// Custom claims for organizations scope
|
||||
organizations?: IOrganizationClaim[];
|
||||
|
||||
// Custom claims for roles scope
|
||||
roles?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Organization claim in ID token / userinfo
|
||||
*/
|
||||
export interface IOrganizationClaim {
|
||||
id: string;
|
||||
name: string;
|
||||
slug: string;
|
||||
roles: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* UserInfo endpoint response
|
||||
*/
|
||||
export interface IUserInfoResponse {
|
||||
/** Subject (user ID) - always included */
|
||||
sub: string;
|
||||
|
||||
// Profile scope
|
||||
name?: string;
|
||||
preferred_username?: string;
|
||||
picture?: string;
|
||||
|
||||
// Email scope
|
||||
email?: string;
|
||||
email_verified?: boolean;
|
||||
|
||||
// Organizations scope (custom)
|
||||
organizations?: IOrganizationClaim[];
|
||||
|
||||
// Roles scope (custom)
|
||||
roles?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Token endpoint response
|
||||
*/
|
||||
export interface ITokenResponse {
|
||||
access_token: string;
|
||||
token_type: 'Bearer';
|
||||
expires_in: number;
|
||||
refresh_token?: string;
|
||||
id_token?: string;
|
||||
scope: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Token endpoint error response
|
||||
*/
|
||||
export interface ITokenErrorResponse {
|
||||
error: 'invalid_request' | 'invalid_client' | 'invalid_grant' | 'unauthorized_client' | 'unsupported_grant_type' | 'invalid_scope';
|
||||
error_description?: string;
|
||||
error_uri?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authorization request parameters
|
||||
*/
|
||||
export interface IAuthorizationRequest {
|
||||
client_id: string;
|
||||
redirect_uri: string;
|
||||
response_type: 'code';
|
||||
scope: string;
|
||||
state: string;
|
||||
code_challenge?: string;
|
||||
code_challenge_method?: 'S256';
|
||||
nonce?: string;
|
||||
prompt?: 'none' | 'login' | 'consent';
|
||||
}
|
||||
|
||||
/**
|
||||
* Token request for authorization_code grant
|
||||
*/
|
||||
export interface ITokenRequestAuthCode {
|
||||
grant_type: 'authorization_code';
|
||||
code: string;
|
||||
redirect_uri: string;
|
||||
client_id: string;
|
||||
client_secret?: string;
|
||||
code_verifier?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Token request for refresh_token grant
|
||||
*/
|
||||
export interface ITokenRequestRefresh {
|
||||
grant_type: 'refresh_token';
|
||||
refresh_token: string;
|
||||
client_id: string;
|
||||
client_secret?: string;
|
||||
scope?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Union type for token requests
|
||||
*/
|
||||
export type ITokenRequest = ITokenRequestAuthCode | ITokenRequestRefresh;
|
||||
Reference in New Issue
Block a user