@absolutejs/auth 0.26.0-beta.4 → 0.26.0-beta.6
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.
- package/dist/audit/types.d.ts +1 -1
- package/dist/index.d.ts +138 -2
- package/dist/index.js +1401 -1114
- package/dist/index.js.map +13 -8
- package/dist/portal/config.d.ts +34 -0
- package/dist/portal/inMemorySetupSessionStore.d.ts +2 -0
- package/dist/portal/operations.d.ts +10 -0
- package/dist/portal/postgresSetupSessionStore.d.ts +140 -0
- package/dist/portal/routes.d.ts +160 -0
- package/dist/portal/types.d.ts +16 -0
- package/dist/types.d.ts +12 -0
- package/dist/utils.d.ts +2 -1
- package/package.json +1 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { AuditEmitter } from '../audit/config';
|
|
2
|
+
import type { ScimTokenStore } from '../scim/types';
|
|
3
|
+
import type { SSOConnectionStore, SSOConnectionType } from '../sso/types';
|
|
4
|
+
import type { OrganizationId } from '../tenancy';
|
|
5
|
+
import type { RouteString } from '../types';
|
|
6
|
+
import type { SetupCapability, SetupSessionStore } from './types';
|
|
7
|
+
export declare const DEFAULT_PORTAL_ROUTE: RouteString;
|
|
8
|
+
export declare const DEFAULT_SETUP_SESSION_TTL_MS: number;
|
|
9
|
+
export type PortalConfig = {
|
|
10
|
+
setupSessionStore: SetupSessionStore;
|
|
11
|
+
onScimTokenCreated?: (context: {
|
|
12
|
+
organizationId: OrganizationId;
|
|
13
|
+
tokenId: string;
|
|
14
|
+
}) => void | Promise<void>;
|
|
15
|
+
onSsoConnectionConfigured?: (context: {
|
|
16
|
+
organizationId: OrganizationId;
|
|
17
|
+
type: SSOConnectionType;
|
|
18
|
+
}) => void | Promise<void>;
|
|
19
|
+
portalRoute?: RouteString;
|
|
20
|
+
scimRoute?: RouteString;
|
|
21
|
+
scimTokenStore?: ScimTokenStore;
|
|
22
|
+
ssoConnectionStore?: SSOConnectionStore;
|
|
23
|
+
ssoRoute?: RouteString;
|
|
24
|
+
};
|
|
25
|
+
export type PortalRouteProps = PortalConfig & {
|
|
26
|
+
emit?: AuditEmitter;
|
|
27
|
+
};
|
|
28
|
+
export type SetupSessionRequest = {
|
|
29
|
+
capabilities: SetupCapability[];
|
|
30
|
+
createdBy?: string;
|
|
31
|
+
organizationId: OrganizationId;
|
|
32
|
+
setupSessionDurationMs?: number;
|
|
33
|
+
setupSessionStore: SetupSessionStore;
|
|
34
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type SetupSessionRequest } from './config';
|
|
2
|
+
import type { SetupSession, SetupSessionStore } from './types';
|
|
3
|
+
export declare const createSetupSession: ({ capabilities, createdBy, organizationId, setupSessionDurationMs, setupSessionStore }: SetupSessionRequest) => Promise<{
|
|
4
|
+
setupSession: SetupSession;
|
|
5
|
+
token: string;
|
|
6
|
+
}>;
|
|
7
|
+
export declare const resolveSetupSession: ({ authorization, setupSessionStore }: {
|
|
8
|
+
authorization: string | undefined;
|
|
9
|
+
setupSessionStore: SetupSessionStore;
|
|
10
|
+
}) => Promise<SetupSession | undefined>;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { type AnyPgDatabase } from '../stores/postgres';
|
|
2
|
+
import type { SetupCapability, SetupSessionStore } from './types';
|
|
3
|
+
export declare const setupSessionsTable: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
4
|
+
name: "auth_setup_sessions";
|
|
5
|
+
schema: undefined;
|
|
6
|
+
columns: {
|
|
7
|
+
capabilities: import("drizzle-orm/pg-core").PgColumn<{
|
|
8
|
+
name: "capabilities";
|
|
9
|
+
tableName: "auth_setup_sessions";
|
|
10
|
+
dataType: "json";
|
|
11
|
+
columnType: "PgJsonb";
|
|
12
|
+
data: SetupCapability[];
|
|
13
|
+
driverParam: unknown;
|
|
14
|
+
notNull: true;
|
|
15
|
+
hasDefault: true;
|
|
16
|
+
isPrimaryKey: false;
|
|
17
|
+
isAutoincrement: false;
|
|
18
|
+
hasRuntimeDefault: false;
|
|
19
|
+
enumValues: undefined;
|
|
20
|
+
baseColumn: never;
|
|
21
|
+
identity: undefined;
|
|
22
|
+
generated: undefined;
|
|
23
|
+
}, {}, {
|
|
24
|
+
$type: SetupCapability[];
|
|
25
|
+
}>;
|
|
26
|
+
created_at_ms: import("drizzle-orm/pg-core").PgColumn<{
|
|
27
|
+
name: "created_at_ms";
|
|
28
|
+
tableName: "auth_setup_sessions";
|
|
29
|
+
dataType: "number";
|
|
30
|
+
columnType: "PgBigInt53";
|
|
31
|
+
data: number;
|
|
32
|
+
driverParam: string | number;
|
|
33
|
+
notNull: true;
|
|
34
|
+
hasDefault: false;
|
|
35
|
+
isPrimaryKey: false;
|
|
36
|
+
isAutoincrement: false;
|
|
37
|
+
hasRuntimeDefault: false;
|
|
38
|
+
enumValues: undefined;
|
|
39
|
+
baseColumn: never;
|
|
40
|
+
identity: undefined;
|
|
41
|
+
generated: undefined;
|
|
42
|
+
}, {}, {}>;
|
|
43
|
+
created_by: import("drizzle-orm/pg-core").PgColumn<{
|
|
44
|
+
name: "created_by";
|
|
45
|
+
tableName: "auth_setup_sessions";
|
|
46
|
+
dataType: "string";
|
|
47
|
+
columnType: "PgVarchar";
|
|
48
|
+
data: string;
|
|
49
|
+
driverParam: string;
|
|
50
|
+
notNull: false;
|
|
51
|
+
hasDefault: false;
|
|
52
|
+
isPrimaryKey: false;
|
|
53
|
+
isAutoincrement: false;
|
|
54
|
+
hasRuntimeDefault: false;
|
|
55
|
+
enumValues: [string, ...string[]];
|
|
56
|
+
baseColumn: never;
|
|
57
|
+
identity: undefined;
|
|
58
|
+
generated: undefined;
|
|
59
|
+
}, {}, {
|
|
60
|
+
length: 255;
|
|
61
|
+
}>;
|
|
62
|
+
expires_at_ms: import("drizzle-orm/pg-core").PgColumn<{
|
|
63
|
+
name: "expires_at_ms";
|
|
64
|
+
tableName: "auth_setup_sessions";
|
|
65
|
+
dataType: "number";
|
|
66
|
+
columnType: "PgBigInt53";
|
|
67
|
+
data: number;
|
|
68
|
+
driverParam: string | number;
|
|
69
|
+
notNull: true;
|
|
70
|
+
hasDefault: false;
|
|
71
|
+
isPrimaryKey: false;
|
|
72
|
+
isAutoincrement: false;
|
|
73
|
+
hasRuntimeDefault: false;
|
|
74
|
+
enumValues: undefined;
|
|
75
|
+
baseColumn: never;
|
|
76
|
+
identity: undefined;
|
|
77
|
+
generated: undefined;
|
|
78
|
+
}, {}, {}>;
|
|
79
|
+
organization_id: import("drizzle-orm/pg-core").PgColumn<{
|
|
80
|
+
name: "organization_id";
|
|
81
|
+
tableName: "auth_setup_sessions";
|
|
82
|
+
dataType: "string";
|
|
83
|
+
columnType: "PgVarchar";
|
|
84
|
+
data: string;
|
|
85
|
+
driverParam: string;
|
|
86
|
+
notNull: true;
|
|
87
|
+
hasDefault: false;
|
|
88
|
+
isPrimaryKey: false;
|
|
89
|
+
isAutoincrement: false;
|
|
90
|
+
hasRuntimeDefault: false;
|
|
91
|
+
enumValues: [string, ...string[]];
|
|
92
|
+
baseColumn: never;
|
|
93
|
+
identity: undefined;
|
|
94
|
+
generated: undefined;
|
|
95
|
+
}, {}, {
|
|
96
|
+
length: 255;
|
|
97
|
+
}>;
|
|
98
|
+
setup_session_id: import("drizzle-orm/pg-core").PgColumn<{
|
|
99
|
+
name: "setup_session_id";
|
|
100
|
+
tableName: "auth_setup_sessions";
|
|
101
|
+
dataType: "string";
|
|
102
|
+
columnType: "PgVarchar";
|
|
103
|
+
data: string;
|
|
104
|
+
driverParam: string;
|
|
105
|
+
notNull: true;
|
|
106
|
+
hasDefault: false;
|
|
107
|
+
isPrimaryKey: true;
|
|
108
|
+
isAutoincrement: false;
|
|
109
|
+
hasRuntimeDefault: false;
|
|
110
|
+
enumValues: [string, ...string[]];
|
|
111
|
+
baseColumn: never;
|
|
112
|
+
identity: undefined;
|
|
113
|
+
generated: undefined;
|
|
114
|
+
}, {}, {
|
|
115
|
+
length: 255;
|
|
116
|
+
}>;
|
|
117
|
+
token_hash: import("drizzle-orm/pg-core").PgColumn<{
|
|
118
|
+
name: "token_hash";
|
|
119
|
+
tableName: "auth_setup_sessions";
|
|
120
|
+
dataType: "string";
|
|
121
|
+
columnType: "PgVarchar";
|
|
122
|
+
data: string;
|
|
123
|
+
driverParam: string;
|
|
124
|
+
notNull: true;
|
|
125
|
+
hasDefault: false;
|
|
126
|
+
isPrimaryKey: false;
|
|
127
|
+
isAutoincrement: false;
|
|
128
|
+
hasRuntimeDefault: false;
|
|
129
|
+
enumValues: [string, ...string[]];
|
|
130
|
+
baseColumn: never;
|
|
131
|
+
identity: undefined;
|
|
132
|
+
generated: undefined;
|
|
133
|
+
}, {}, {
|
|
134
|
+
length: 255;
|
|
135
|
+
}>;
|
|
136
|
+
};
|
|
137
|
+
dialect: "pg";
|
|
138
|
+
}>;
|
|
139
|
+
export declare const createNeonSetupSessionStore: (databaseUrl: string) => SetupSessionStore;
|
|
140
|
+
export declare const createPostgresSetupSessionStore: (db: AnyPgDatabase) => SetupSessionStore;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { Elysia } from 'elysia';
|
|
2
|
+
import { type PortalRouteProps } from './config';
|
|
3
|
+
export declare const portalRoutes: ({ emit, onScimTokenCreated, onSsoConnectionConfigured, portalRoute, scimRoute, scimTokenStore, setupSessionStore, ssoConnectionStore, ssoRoute }: PortalRouteProps) => Elysia<"", {
|
|
4
|
+
decorator: {};
|
|
5
|
+
store: {};
|
|
6
|
+
derive: {};
|
|
7
|
+
resolve: {};
|
|
8
|
+
}, {
|
|
9
|
+
typebox: {};
|
|
10
|
+
error: {};
|
|
11
|
+
}, {
|
|
12
|
+
schema: {};
|
|
13
|
+
standaloneSchema: {};
|
|
14
|
+
macro: {};
|
|
15
|
+
macroFn: {};
|
|
16
|
+
parser: {};
|
|
17
|
+
response: {};
|
|
18
|
+
}, {
|
|
19
|
+
[x: string]: {
|
|
20
|
+
session: {
|
|
21
|
+
get: {
|
|
22
|
+
body: unknown;
|
|
23
|
+
params: {};
|
|
24
|
+
query: unknown;
|
|
25
|
+
headers: unknown;
|
|
26
|
+
response: {
|
|
27
|
+
200: {
|
|
28
|
+
readonly capabilities: import("./types").SetupCapability[];
|
|
29
|
+
readonly configured: {
|
|
30
|
+
readonly oidc: boolean;
|
|
31
|
+
readonly saml: boolean;
|
|
32
|
+
};
|
|
33
|
+
readonly expiresAt: number;
|
|
34
|
+
readonly oidc: {
|
|
35
|
+
redirectUri: string;
|
|
36
|
+
} | undefined;
|
|
37
|
+
readonly organizationId: string;
|
|
38
|
+
readonly saml: {
|
|
39
|
+
acsUrl: string;
|
|
40
|
+
entityId: string;
|
|
41
|
+
metadataUrl: string;
|
|
42
|
+
} | undefined;
|
|
43
|
+
readonly scim: {
|
|
44
|
+
baseUrl: string;
|
|
45
|
+
} | undefined;
|
|
46
|
+
};
|
|
47
|
+
401: "Invalid or expired setup link";
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
} & {
|
|
53
|
+
[x: string]: {
|
|
54
|
+
connection: {
|
|
55
|
+
saml: {
|
|
56
|
+
put: {
|
|
57
|
+
body: {
|
|
58
|
+
idpSloUrl?: string | undefined;
|
|
59
|
+
idpEntityId: string;
|
|
60
|
+
idpSsoUrl: string;
|
|
61
|
+
idpX509Cert: string;
|
|
62
|
+
};
|
|
63
|
+
params: {};
|
|
64
|
+
query: unknown;
|
|
65
|
+
headers: unknown;
|
|
66
|
+
response: {
|
|
67
|
+
200: {
|
|
68
|
+
readonly configured: true;
|
|
69
|
+
readonly type: "saml";
|
|
70
|
+
};
|
|
71
|
+
401: "Invalid or expired setup link";
|
|
72
|
+
403: "This setup link cannot configure SAML";
|
|
73
|
+
422: {
|
|
74
|
+
type: "validation";
|
|
75
|
+
on: string;
|
|
76
|
+
summary?: string;
|
|
77
|
+
message?: string;
|
|
78
|
+
found?: unknown;
|
|
79
|
+
property?: string;
|
|
80
|
+
expected?: string;
|
|
81
|
+
};
|
|
82
|
+
501: "SSO is not configured";
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
} & {
|
|
89
|
+
[x: string]: {
|
|
90
|
+
connection: {
|
|
91
|
+
oidc: {
|
|
92
|
+
put: {
|
|
93
|
+
body: {
|
|
94
|
+
redirectUri?: string | undefined;
|
|
95
|
+
scopes?: string[] | undefined;
|
|
96
|
+
issuer: string;
|
|
97
|
+
clientId: string;
|
|
98
|
+
clientSecret: string;
|
|
99
|
+
};
|
|
100
|
+
params: {};
|
|
101
|
+
query: unknown;
|
|
102
|
+
headers: unknown;
|
|
103
|
+
response: {
|
|
104
|
+
200: {
|
|
105
|
+
readonly configured: true;
|
|
106
|
+
readonly type: "oidc";
|
|
107
|
+
};
|
|
108
|
+
401: "Invalid or expired setup link";
|
|
109
|
+
403: "This setup link cannot configure OIDC";
|
|
110
|
+
422: {
|
|
111
|
+
type: "validation";
|
|
112
|
+
on: string;
|
|
113
|
+
summary?: string;
|
|
114
|
+
message?: string;
|
|
115
|
+
found?: unknown;
|
|
116
|
+
property?: string;
|
|
117
|
+
expected?: string;
|
|
118
|
+
};
|
|
119
|
+
501: "SSO is not configured";
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
} & {
|
|
126
|
+
[x: string]: {
|
|
127
|
+
scim: {
|
|
128
|
+
token: {
|
|
129
|
+
post: {
|
|
130
|
+
body: unknown;
|
|
131
|
+
params: {};
|
|
132
|
+
query: unknown;
|
|
133
|
+
headers: unknown;
|
|
134
|
+
response: {
|
|
135
|
+
200: {
|
|
136
|
+
readonly baseUrl: `${string}/${string}`;
|
|
137
|
+
readonly token: string;
|
|
138
|
+
readonly tokenId: string;
|
|
139
|
+
};
|
|
140
|
+
401: "Invalid or expired setup link";
|
|
141
|
+
403: "This setup link cannot configure SCIM";
|
|
142
|
+
501: "SCIM is not configured";
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
}, {
|
|
149
|
+
derive: {};
|
|
150
|
+
resolve: {};
|
|
151
|
+
schema: {};
|
|
152
|
+
standaloneSchema: {};
|
|
153
|
+
response: {};
|
|
154
|
+
}, {
|
|
155
|
+
derive: {};
|
|
156
|
+
resolve: {};
|
|
157
|
+
schema: {};
|
|
158
|
+
standaloneSchema: {};
|
|
159
|
+
response: {};
|
|
160
|
+
}>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { OrganizationId } from '../tenancy';
|
|
2
|
+
export type SetupCapability = 'scim' | 'sso_oidc' | 'sso_saml';
|
|
3
|
+
export type SetupSession = {
|
|
4
|
+
capabilities: SetupCapability[];
|
|
5
|
+
createdAt: number;
|
|
6
|
+
createdBy?: string;
|
|
7
|
+
expiresAt: number;
|
|
8
|
+
organizationId: OrganizationId;
|
|
9
|
+
setupSessionId: string;
|
|
10
|
+
tokenHash: string;
|
|
11
|
+
};
|
|
12
|
+
export type SetupSessionStore = {
|
|
13
|
+
deleteSetupSession: (setupSessionId: string) => Promise<void>;
|
|
14
|
+
getSetupSessionByTokenHash: (tokenHash: string) => Promise<SetupSession | undefined>;
|
|
15
|
+
saveSetupSession: (session: SetupSession) => Promise<void>;
|
|
16
|
+
};
|
package/dist/types.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type { LockoutConfig } from './lockout/config';
|
|
|
11
11
|
import type { MfaConfig } from './mfa/config';
|
|
12
12
|
import type { OrganizationsConfig } from './organizations/config';
|
|
13
13
|
import type { PasswordlessConfig } from './passwordless/config';
|
|
14
|
+
import type { PortalConfig } from './portal/config';
|
|
14
15
|
import type { RolesConfig } from './roles/config';
|
|
15
16
|
import type { ScimConfig } from './scim/config';
|
|
16
17
|
import type { SessionsConfig } from './session/sessionsConfig';
|
|
@@ -217,6 +218,11 @@ export type AuthConfig<UserType> = {
|
|
|
217
218
|
* one (caller becomes owner), invite/accept/revoke by email, and list/remove members. Ties the
|
|
218
219
|
* bare `organizationId` used by SSO/SCIM/RBAC into a real tenant model with org-scoped roles. */
|
|
219
220
|
organizations?: OrganizationsConfig<UserType>;
|
|
221
|
+
/** Admin portal — the WorkOS self-serve "setup link" model, headless. When present, mounts
|
|
222
|
+
* `{portalRoute}` endpoints a customer's IT admin (holding a scoped setup token from
|
|
223
|
+
* `createSetupSession`) calls to read the service-provider URLs and configure their own SSO
|
|
224
|
+
* connection / SCIM token. JSON contract, so the portal UI can be built in any framework. */
|
|
225
|
+
portal?: PortalConfig;
|
|
220
226
|
/** Org-scoped roles & permissions (builds on `organizations`). When present, mounts routes to
|
|
221
227
|
* list an org's role definitions and set a member's roles. Pair with
|
|
222
228
|
* `createMembershipPermissionResolver` to make `authorization.hasPermission` turnkey. */
|
|
@@ -268,6 +274,12 @@ export type AuthConfig<UserType> = {
|
|
|
268
274
|
onProfileError?: OnProfileError;
|
|
269
275
|
onSessionCleanup?: OnSessionCleanup<UserType>;
|
|
270
276
|
};
|
|
277
|
+
/** The serializable subset of `AuthConfig` — the route paths, session durations, and
|
|
278
|
+
* limits that can live in a data file (`auth.config.ts` via `defineAuthSettings`) and
|
|
279
|
+
* be edited from tooling, separate from the code wiring (stores, hooks, callbacks)
|
|
280
|
+
* that stays in the `auth()` call. Spread alongside the rest:
|
|
281
|
+
* `auth({ ...defineAuthSettings({...}), authSessionStore, providersConfiguration })`. */
|
|
282
|
+
export type AuthSettings = Pick<AuthConfig<unknown>, 'authorizeRoute' | 'callbackRoute' | 'cleanupIntervalMs' | 'maxSessions' | 'profileRoute' | 'refreshRoute' | 'revokeRoute' | 'sessionDurationMs' | 'signoutRoute' | 'statusRoute' | 'unregisteredSessionDurationMs'>;
|
|
271
283
|
export type ClientProviderEntry = {
|
|
272
284
|
clientName?: string;
|
|
273
285
|
providerInstance: OAuth2Client<ProviderOption>;
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { OAuth2Client, OAuth2TokenResponse, ProviderOption } from 'citra';
|
|
2
2
|
import { Cookie } from 'elysia';
|
|
3
3
|
import { AuthHtmxConfig } from './htmx/types';
|
|
4
|
-
import { AuthConfig, InsantiateUserSessionProps, OAuth2ConfigurationOptions, ResolvedOAuthAuthorization, SessionRecord, UnregisteredSessionRecord, UserSessionId } from './types';
|
|
4
|
+
import { AuthConfig, AuthSettings, InsantiateUserSessionProps, OAuth2ConfigurationOptions, ResolvedOAuthAuthorization, SessionRecord, UnregisteredSessionRecord, UserSessionId } from './types';
|
|
5
5
|
export declare const defineAuthConfig: <UserType>(configuration: AuthConfig<UserType>) => AuthConfig<UserType>;
|
|
6
6
|
export declare const defineAuthHtmxConfig: (htmxConfig: AuthHtmxConfig) => AuthHtmxConfig;
|
|
7
|
+
export declare const defineAuthSettings: (settings: AuthSettings) => AuthSettings;
|
|
7
8
|
export declare const defineProvidersConfiguration: (providersConfiguration: OAuth2ConfigurationOptions) => OAuth2ConfigurationOptions;
|
|
8
9
|
export declare const getStatus: <UserType>(session: SessionRecord<UserType>, user_session_id: Cookie<UserSessionId | undefined>) => Promise<{
|
|
9
10
|
error: {
|
package/package.json
CHANGED