feat(center): OIDC login (auto-provision by email) + CLI config-oidc
- OidcConfig entity (single row) + DB registration.
- OidcService: discovery, Authorization Code + PKCE, state/ticket as
short-lived signed JWTs (no server session), userinfo/id_token claim
resolution. Auto-provisions a passwordless user by email.
- Public endpoints /auth/oidc/{status,start,callback,exchange}; callback
bounces a one-time ticket to the SPA in the URL fragment.
- AuthService.provisionOidcUser + issueSessionForUserId (login shape).
- CLI: 'config oidc' upserts issuer/clientId/secret/callback/redirect/
scopes/enabled (secret masked on print).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
37
src/entities/oidc-config.entity.ts
Normal file
37
src/entities/oidc-config.entity.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { Column, Entity, PrimaryColumn, UpdateDateColumn } from 'typeorm';
|
||||
|
||||
// Single-row OIDC provider configuration, managed via the CLI
|
||||
// `config-oidc`. id is always 'default'.
|
||||
@Entity('oidc_config')
|
||||
export class OidcConfig {
|
||||
@PrimaryColumn({ type: 'varchar', length: 16 })
|
||||
id!: string; // always 'default'
|
||||
|
||||
@Column({ type: 'varchar', length: 512, default: '' })
|
||||
issuer!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 256, default: '' })
|
||||
clientId!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 512, default: '' })
|
||||
clientSecret!: string;
|
||||
|
||||
// Center's own callback URL registered at the IdP, e.g.
|
||||
// https://fabric-api.example/api/auth/oidc/callback
|
||||
@Column({ type: 'varchar', length: 512, default: '' })
|
||||
redirectUri!: string;
|
||||
|
||||
// Where to send the browser back after a successful login (the SPA),
|
||||
// e.g. https://fabric.example/oidc
|
||||
@Column({ type: 'varchar', length: 512, default: '' })
|
||||
postLoginRedirect!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 256, default: 'openid email profile' })
|
||||
scopes!: string;
|
||||
|
||||
@Column({ type: 'boolean', default: false })
|
||||
enabled!: boolean;
|
||||
|
||||
@UpdateDateColumn()
|
||||
updatedAt!: Date;
|
||||
}
|
||||
Reference in New Issue
Block a user