@absolutejs/auth 0.27.0-beta.2 → 0.27.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,138 @@
1
+ import { Elysia } from 'elysia';
2
+ import type { AuthSessionStore } from '../session/types';
3
+ import { type OidcProviderConfig } from './config';
4
+ export declare const oidcProviderRoutes: <UserType>(config: OidcProviderConfig<UserType> & {
5
+ authSessionStore?: AuthSessionStore<UserType>;
6
+ }) => Elysia<"", {
7
+ decorator: {};
8
+ store: {
9
+ session: import("..").SessionRecord<UserType>;
10
+ unregisteredSession: import("..").UnregisteredSessionRecord;
11
+ };
12
+ derive: {};
13
+ resolve: {};
14
+ }, {
15
+ typebox: {};
16
+ error: {};
17
+ }, {
18
+ schema: {};
19
+ standaloneSchema: {};
20
+ macro: {};
21
+ macroFn: {};
22
+ parser: {};
23
+ response: {};
24
+ }, {
25
+ [x: string]: {
26
+ get: {
27
+ body: unknown;
28
+ params: {};
29
+ query: {
30
+ nonce?: string | undefined;
31
+ client_id?: string | undefined;
32
+ scope?: string | undefined;
33
+ code_challenge?: string | undefined;
34
+ code_challenge_method?: string | undefined;
35
+ redirect_uri?: string | undefined;
36
+ response_type?: string | undefined;
37
+ state?: string | undefined;
38
+ };
39
+ headers: unknown;
40
+ response: {
41
+ 200: Response;
42
+ 422: {
43
+ type: "validation";
44
+ on: string;
45
+ summary?: string;
46
+ message?: string;
47
+ found?: unknown;
48
+ property?: string;
49
+ expected?: string;
50
+ };
51
+ };
52
+ };
53
+ };
54
+ } & {
55
+ [x: string]: {
56
+ post: {
57
+ body: {
58
+ client_id?: string | undefined;
59
+ scope?: string | undefined;
60
+ refresh_token?: string | undefined;
61
+ client_secret?: string | undefined;
62
+ grant_type?: string | undefined;
63
+ code?: string | undefined;
64
+ redirect_uri?: string | undefined;
65
+ code_verifier?: string | undefined;
66
+ };
67
+ params: {};
68
+ query: unknown;
69
+ headers: unknown;
70
+ response: {
71
+ 200: Response;
72
+ 422: {
73
+ type: "validation";
74
+ on: string;
75
+ summary?: string;
76
+ message?: string;
77
+ found?: unknown;
78
+ property?: string;
79
+ expected?: string;
80
+ };
81
+ };
82
+ };
83
+ };
84
+ } & {
85
+ [x: string]: {
86
+ get: {
87
+ body: unknown;
88
+ params: {};
89
+ query: unknown;
90
+ headers: unknown;
91
+ response: {
92
+ 200: {
93
+ keys: {
94
+ alg: string;
95
+ crv: string | undefined;
96
+ kid: string;
97
+ kty: string | undefined;
98
+ use: string;
99
+ x: string | undefined;
100
+ y: string | undefined;
101
+ }[];
102
+ };
103
+ };
104
+ };
105
+ };
106
+ } & {
107
+ ".well-known": {
108
+ "openid-configuration": {
109
+ get: {
110
+ body: unknown;
111
+ params: {};
112
+ query: unknown;
113
+ headers: unknown;
114
+ response: {
115
+ 200: Record<string, string | string[]>;
116
+ };
117
+ };
118
+ };
119
+ };
120
+ }, {
121
+ derive: {};
122
+ resolve: {};
123
+ schema: {};
124
+ standaloneSchema: {};
125
+ response: {};
126
+ }, {
127
+ derive: {};
128
+ resolve: {};
129
+ schema: {};
130
+ standaloneSchema: {};
131
+ response: {};
132
+ } & {
133
+ derive: {};
134
+ resolve: {};
135
+ schema: {};
136
+ standaloneSchema: {};
137
+ response: {};
138
+ }>;
@@ -0,0 +1,42 @@
1
+ export type OAuthClient = {
2
+ clientId: string;
3
+ hashedSecret?: string;
4
+ name: string;
5
+ redirectUris: string[];
6
+ scopes: string[];
7
+ };
8
+ export type OAuthClientStore = {
9
+ findClient: (clientId: string) => Promise<OAuthClient | undefined>;
10
+ };
11
+ export type AuthorizationCode = {
12
+ claims?: Record<string, unknown>;
13
+ clientId: string;
14
+ codeChallenge: string;
15
+ codeHash: string;
16
+ createdAt: number;
17
+ dpopJkt?: string;
18
+ expiresAt: number;
19
+ nonce?: string;
20
+ redirectUri: string;
21
+ scopes: string[];
22
+ userId: string;
23
+ };
24
+ export type AuthorizationCodeStore = {
25
+ consumeCode: (codeHash: string) => Promise<AuthorizationCode | undefined>;
26
+ saveCode: (code: AuthorizationCode) => Promise<void>;
27
+ };
28
+ export type OidcRefreshToken = {
29
+ claims?: Record<string, unknown>;
30
+ clientId: string;
31
+ createdAt: number;
32
+ dpopJkt?: string;
33
+ expiresAt: number;
34
+ scopes: string[];
35
+ tokenHash: string;
36
+ userId: string;
37
+ };
38
+ export type OidcRefreshTokenStore = {
39
+ consumeToken: (tokenHash: string) => Promise<OidcRefreshToken | undefined>;
40
+ deleteForUser: (userId: string) => Promise<void>;
41
+ saveToken: (token: OidcRefreshToken) => Promise<void>;
42
+ };
@@ -0,0 +1,29 @@
1
+ import type { Cookie } from 'elysia';
2
+ import type { AuditEvent } from '../audit/types';
3
+ import type { SessionData, SessionRecord, UserSessionId } from '../types';
4
+ import type { AuthSessionStore } from './types';
5
+ type Emit = (event: AuditEvent) => Promise<void> | void;
6
+ export declare const endImpersonation: <UserType>({ authSessionStore, cookie, emit, inMemorySession }: {
7
+ authSessionStore?: AuthSessionStore<UserType>;
8
+ cookie: Cookie<UserSessionId | undefined>;
9
+ emit?: Emit;
10
+ inMemorySession: SessionRecord<UserType>;
11
+ }) => Promise<{
12
+ restored: boolean;
13
+ }>;
14
+ export declare const isImpersonating: <UserType>(session: SessionData<UserType> | undefined) => boolean;
15
+ export declare const startImpersonation: <UserType>({ authSessionStore, cookie, emit, getUserId, impersonator, inMemorySession, sessionDurationMs, user }: {
16
+ authSessionStore?: AuthSessionStore<UserType>;
17
+ cookie: Cookie<UserSessionId | undefined>;
18
+ emit?: Emit;
19
+ getUserId?: (user: UserType) => string;
20
+ impersonator: {
21
+ actorEmail?: string;
22
+ actorId: string;
23
+ reason: string;
24
+ };
25
+ inMemorySession: SessionRecord<UserType>;
26
+ sessionDurationMs?: number;
27
+ user: UserType;
28
+ }) => Promise<`${string}-${string}-${string}-${string}-${string}`>;
29
+ export {};
@@ -11,10 +11,11 @@ export declare const persistWhen: (shouldPersist: boolean, persist: () => Promis
11
11
  type PromoteToSessionProps<UserType> = {
12
12
  authSessionStore?: AuthSessionStore<UserType>;
13
13
  cookie: Cookie<UserSessionId | undefined>;
14
+ impersonator?: SessionData<UserType>['impersonator'];
14
15
  inMemorySession: SessionRecord<UserType>;
15
16
  samlLogout?: SessionData<UserType>['samlLogout'];
16
17
  sessionDurationMs: number;
17
18
  user: UserType;
18
19
  };
19
- export declare const promoteToSession: <UserType>({ authSessionStore, cookie, inMemorySession, samlLogout, sessionDurationMs, user }: PromoteToSessionProps<UserType>) => Promise<`${string}-${string}-${string}-${string}-${string}`>;
20
+ export declare const promoteToSession: <UserType>({ authSessionStore, cookie, impersonator, inMemorySession, samlLogout, sessionDurationMs, user }: PromoteToSessionProps<UserType>) => Promise<`${string}-${string}-${string}-${string}-${string}`>;
20
21
  export {};
package/dist/types.d.ts CHANGED
@@ -10,6 +10,7 @@ import type { AuthIdentityConflict } from './errors';
10
10
  import type { AuthHtmxConfig, AuthHtmxUser } from './htmx/types';
11
11
  import type { LockoutConfig } from './lockout/config';
12
12
  import type { MfaConfig } from './mfa/config';
13
+ import type { OidcProviderConfig } from './oidc/config';
13
14
  import type { OrganizationsConfig } from './organizations/config';
14
15
  import type { PasswordlessConfig } from './passwordless/config';
15
16
  import type { PortalConfig } from './portal/config';
@@ -34,6 +35,17 @@ export type OAuth2ConfigurationOptions = {
34
35
  [Provider in ProviderOption]?: OAuth2ProviderConfiguration<Provider>;
35
36
  };
36
37
  export type UserSessionId = `${string}-${string}-${string}-${string}-${string}`;
38
+ /** Stamped on a session created via admin impersonation (`startImpersonation`). RFC 8693
39
+ * actor semantics: `actorId`/`actorEmail` are the admin acting as the user, `reason` is
40
+ * required and audited, `returnToSessionId` is the admin's own session to restore on exit.
41
+ * Surfaced by userStatus so your UI can show an "impersonating" banner. */
42
+ export type Impersonator = {
43
+ actorEmail?: string;
44
+ actorId: string;
45
+ reason: string;
46
+ returnToSessionId?: UserSessionId;
47
+ startedAt: number;
48
+ };
37
49
  export type SessionData<UserType> = {
38
50
  user: UserType;
39
51
  /** OAuth provider access token. Optional: credential / SSO sessions are not backed
@@ -53,6 +65,8 @@ export type SessionData<UserType> = {
53
65
  nameId: string;
54
66
  sessionIndex?: string;
55
67
  };
68
+ /** Present only when this session was created via admin impersonation. */
69
+ impersonator?: Impersonator;
56
70
  };
57
71
  export type SessionRecord<UserType> = Record<UserSessionId, SessionData<UserType>>;
58
72
  export type UnregisteredSessionData = {
@@ -221,6 +235,13 @@ export type AuthConfig<UserType> = {
221
235
  * Pair with the exported `createApiKey` / `resolveApiPrincipal` / `hasScopes`
222
236
  * helpers to issue and guard with static keys. */
223
237
  apikeys?: ApiKeysConfig;
238
+ /** OAuth2 / OIDC provider — makes your app an identity provider ("Sign in with
239
+ * <yourapp>"). Mounts `{oidcRoute}/authorize` + `/token` + `/jwks` and
240
+ * `/.well-known/openid-configuration`: authorization_code + mandatory PKCE, ES256
241
+ * JWTs signed by a key you own (self-hosted JWKS), refresh-token rotation, and
242
+ * optional DPoP (RFC 9449) sender-constrained tokens. The authorize endpoint reuses
243
+ * the package session, so the IdP login gets passkeys / MFA / SSO for free. */
244
+ oidc?: OidcProviderConfig<UserType>;
224
245
  /** First-class multi-tenancy (the WorkOS model). When present, mounts organization +
225
246
  * membership + invitation routes under `{organizationsRoute}`: list the caller's orgs, create
226
247
  * one (caller becomes owner), invite/accept/revoke by email, and list/remove members. Ties the
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.27.0-beta.2",
2
+ "version": "0.27.0-beta.4",
3
3
  "name": "@absolutejs/auth",
4
4
  "description": "An authorization library for absolutejs",
5
5
  "repository": {