@absolutejs/auth 0.26.0-beta.2 → 0.26.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.
- package/dist/audit/config.d.ts +2 -1
- package/dist/audit/types.d.ts +1 -1
- package/dist/authorization/config.d.ts +19 -0
- package/dist/authorization/protectPermission.d.ts +52 -0
- package/dist/compliance/cipher.d.ts +5 -0
- package/dist/compliance/config.d.ts +18 -0
- package/dist/compliance/redaction.d.ts +8 -0
- package/dist/compliance/routes.d.ts +89 -0
- package/dist/htmx/index.js +494 -98
- package/dist/htmx/index.js.map +3 -3
- package/dist/index.d.ts +7578 -430
- package/dist/index.js +4601 -1490
- package/dist/index.js.map +50 -13
- package/dist/organizations/config.d.ts +46 -0
- package/dist/organizations/inMemoryOrganizationStore.d.ts +2 -0
- package/dist/organizations/operations.d.ts +32 -0
- package/dist/organizations/postgresOrganizationStore.d.ts +412 -0
- package/dist/organizations/routes.d.ts +299 -0
- package/dist/organizations/types.d.ts +44 -0
- package/dist/passwordless/config.d.ts +42 -0
- package/dist/passwordless/inMemoryPasswordlessTokenStore.d.ts +2 -0
- package/dist/passwordless/postgresPasswordlessTokenStore.d.ts +66 -0
- package/dist/passwordless/routes.d.ts +163 -0
- package/dist/passwordless/types.d.ts +9 -0
- package/dist/providers/clients.d.ts +3 -3
- package/dist/roles/config.d.ts +27 -0
- package/dist/roles/inMemoryRoleStore.d.ts +2 -0
- package/dist/roles/operations.d.ts +8 -0
- package/dist/roles/postgresRoleStore.d.ts +102 -0
- package/dist/roles/resolver.d.ts +17 -0
- package/dist/roles/routes.d.ts +106 -0
- package/dist/roles/types.d.ts +14 -0
- package/dist/routes/authorize.d.ts +2 -2
- package/dist/routes/protectRoute.d.ts +2 -2
- package/dist/scim/config.d.ts +55 -0
- package/dist/scim/inMemoryScimTokenStore.d.ts +2 -0
- package/dist/scim/postgresScimTokenStore.d.ts +102 -0
- package/dist/scim/routes.d.ts +296 -0
- package/dist/scim/serialize.d.ts +45 -0
- package/dist/scim/types.d.ts +52 -0
- package/dist/session/promote.d.ts +9 -2
- package/dist/sso/config.d.ts +104 -0
- package/dist/sso/discoveryRoute.d.ts +63 -0
- package/dist/sso/inMemorySsoConnectionStore.d.ts +2 -0
- package/dist/sso/oidcRoutes.d.ts +97 -0
- package/dist/sso/postgresSsoConnectionStore.d.ts +139 -0
- package/dist/sso/samlRoutes.d.ts +176 -0
- package/dist/sso/types.d.ts +39 -0
- package/dist/typebox.d.ts +1 -1
- package/dist/types.d.ts +59 -0
- package/dist/webauthn/adapter.d.ts +59 -0
- package/dist/webauthn/config.d.ts +35 -0
- package/dist/webauthn/inMemoryWebAuthnCredentialStore.d.ts +2 -0
- package/dist/webauthn/postgresWebAuthnCredentialStore.d.ts +172 -0
- package/dist/webauthn/routes.d.ts +155 -0
- package/dist/webauthn/types.d.ts +17 -0
- package/dist/webhooks/config.d.ts +21 -0
- package/dist/webhooks/dispatcher.d.ts +3 -0
- package/dist/webhooks/sign.d.ts +11 -0
- package/dist/webhooks/types.d.ts +11 -0
- package/package.json +2 -2
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { type AnyPgDatabase } from '../stores/postgres';
|
|
2
|
+
import type { OidcConnectionConfig, SamlConnectionConfig, SSOConnectionStore, SSOConnectionType } from './types';
|
|
3
|
+
export declare const ssoConnectionsTable: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
4
|
+
name: "auth_sso_connections";
|
|
5
|
+
schema: undefined;
|
|
6
|
+
columns: {
|
|
7
|
+
config: import("drizzle-orm/pg-core").PgColumn<{
|
|
8
|
+
name: "config";
|
|
9
|
+
tableName: "auth_sso_connections";
|
|
10
|
+
dataType: "json";
|
|
11
|
+
columnType: "PgJsonb";
|
|
12
|
+
data: OidcConnectionConfig | SamlConnectionConfig;
|
|
13
|
+
driverParam: unknown;
|
|
14
|
+
notNull: true;
|
|
15
|
+
hasDefault: false;
|
|
16
|
+
isPrimaryKey: false;
|
|
17
|
+
isAutoincrement: false;
|
|
18
|
+
hasRuntimeDefault: false;
|
|
19
|
+
enumValues: undefined;
|
|
20
|
+
baseColumn: never;
|
|
21
|
+
identity: undefined;
|
|
22
|
+
generated: undefined;
|
|
23
|
+
}, {}, {
|
|
24
|
+
$type: OidcConnectionConfig | SamlConnectionConfig;
|
|
25
|
+
}>;
|
|
26
|
+
connection_id: import("drizzle-orm/pg-core").PgColumn<{
|
|
27
|
+
name: "connection_id";
|
|
28
|
+
tableName: "auth_sso_connections";
|
|
29
|
+
dataType: "string";
|
|
30
|
+
columnType: "PgVarchar";
|
|
31
|
+
data: string;
|
|
32
|
+
driverParam: string;
|
|
33
|
+
notNull: true;
|
|
34
|
+
hasDefault: false;
|
|
35
|
+
isPrimaryKey: true;
|
|
36
|
+
isAutoincrement: false;
|
|
37
|
+
hasRuntimeDefault: false;
|
|
38
|
+
enumValues: [string, ...string[]];
|
|
39
|
+
baseColumn: never;
|
|
40
|
+
identity: undefined;
|
|
41
|
+
generated: undefined;
|
|
42
|
+
}, {}, {
|
|
43
|
+
length: 255;
|
|
44
|
+
}>;
|
|
45
|
+
created_at_ms: import("drizzle-orm/pg-core").PgColumn<{
|
|
46
|
+
name: "created_at_ms";
|
|
47
|
+
tableName: "auth_sso_connections";
|
|
48
|
+
dataType: "number";
|
|
49
|
+
columnType: "PgBigInt53";
|
|
50
|
+
data: number;
|
|
51
|
+
driverParam: string | number;
|
|
52
|
+
notNull: true;
|
|
53
|
+
hasDefault: false;
|
|
54
|
+
isPrimaryKey: false;
|
|
55
|
+
isAutoincrement: false;
|
|
56
|
+
hasRuntimeDefault: false;
|
|
57
|
+
enumValues: undefined;
|
|
58
|
+
baseColumn: never;
|
|
59
|
+
identity: undefined;
|
|
60
|
+
generated: undefined;
|
|
61
|
+
}, {}, {}>;
|
|
62
|
+
enabled: import("drizzle-orm/pg-core").PgColumn<{
|
|
63
|
+
name: "enabled";
|
|
64
|
+
tableName: "auth_sso_connections";
|
|
65
|
+
dataType: "boolean";
|
|
66
|
+
columnType: "PgBoolean";
|
|
67
|
+
data: boolean;
|
|
68
|
+
driverParam: boolean;
|
|
69
|
+
notNull: true;
|
|
70
|
+
hasDefault: true;
|
|
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_sso_connections";
|
|
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
|
+
type: import("drizzle-orm/pg-core").PgColumn<{
|
|
99
|
+
name: "type";
|
|
100
|
+
tableName: "auth_sso_connections";
|
|
101
|
+
dataType: "string";
|
|
102
|
+
columnType: "PgVarchar";
|
|
103
|
+
data: SSOConnectionType;
|
|
104
|
+
driverParam: string;
|
|
105
|
+
notNull: true;
|
|
106
|
+
hasDefault: false;
|
|
107
|
+
isPrimaryKey: false;
|
|
108
|
+
isAutoincrement: false;
|
|
109
|
+
hasRuntimeDefault: false;
|
|
110
|
+
enumValues: [string, ...string[]];
|
|
111
|
+
baseColumn: never;
|
|
112
|
+
identity: undefined;
|
|
113
|
+
generated: undefined;
|
|
114
|
+
}, {}, {
|
|
115
|
+
length: 16;
|
|
116
|
+
$type: SSOConnectionType;
|
|
117
|
+
}>;
|
|
118
|
+
updated_at_ms: import("drizzle-orm/pg-core").PgColumn<{
|
|
119
|
+
name: "updated_at_ms";
|
|
120
|
+
tableName: "auth_sso_connections";
|
|
121
|
+
dataType: "number";
|
|
122
|
+
columnType: "PgBigInt53";
|
|
123
|
+
data: number;
|
|
124
|
+
driverParam: string | number;
|
|
125
|
+
notNull: true;
|
|
126
|
+
hasDefault: false;
|
|
127
|
+
isPrimaryKey: false;
|
|
128
|
+
isAutoincrement: false;
|
|
129
|
+
hasRuntimeDefault: false;
|
|
130
|
+
enumValues: undefined;
|
|
131
|
+
baseColumn: never;
|
|
132
|
+
identity: undefined;
|
|
133
|
+
generated: undefined;
|
|
134
|
+
}, {}, {}>;
|
|
135
|
+
};
|
|
136
|
+
dialect: "pg";
|
|
137
|
+
}>;
|
|
138
|
+
export declare const createNeonSsoConnectionStore: (databaseUrl: string) => SSOConnectionStore;
|
|
139
|
+
export declare const createPostgresSsoConnectionStore: (db: AnyPgDatabase) => SSOConnectionStore;
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { Elysia } from 'elysia';
|
|
2
|
+
import type { AuthSessionStore } from '../session/types';
|
|
3
|
+
import type { SessionRecord } from '../types';
|
|
4
|
+
import { type SamlAdapter, type SSOConfig } from './config';
|
|
5
|
+
type SamlRoutesProps<UserType> = SSOConfig<UserType> & {
|
|
6
|
+
authSessionStore?: AuthSessionStore<UserType>;
|
|
7
|
+
samlAdapter: SamlAdapter;
|
|
8
|
+
};
|
|
9
|
+
export declare const samlSsoRoutes: <UserType>({ authSessionStore, getSsoUser, onSsoCallbackError, onSsoCallbackSuccess, samlAdapter, sessionDurationMs, ssoConnectionStore, ssoRoute }: SamlRoutesProps<UserType>) => Elysia<"", {
|
|
10
|
+
decorator: {};
|
|
11
|
+
store: {
|
|
12
|
+
session: SessionRecord<UserType>;
|
|
13
|
+
unregisteredSession: import("..").UnregisteredSessionRecord;
|
|
14
|
+
};
|
|
15
|
+
derive: {};
|
|
16
|
+
resolve: {};
|
|
17
|
+
}, {
|
|
18
|
+
typebox: {};
|
|
19
|
+
error: {};
|
|
20
|
+
}, {
|
|
21
|
+
schema: {};
|
|
22
|
+
standaloneSchema: {};
|
|
23
|
+
macro: {};
|
|
24
|
+
macroFn: {};
|
|
25
|
+
parser: {};
|
|
26
|
+
response: {};
|
|
27
|
+
}, {
|
|
28
|
+
[x: string]: {
|
|
29
|
+
get: {
|
|
30
|
+
body: unknown;
|
|
31
|
+
params: {
|
|
32
|
+
organizationId: string;
|
|
33
|
+
};
|
|
34
|
+
query: unknown;
|
|
35
|
+
headers: unknown;
|
|
36
|
+
response: {
|
|
37
|
+
200: Response;
|
|
38
|
+
404: "No SAML connection is configured for this organization";
|
|
39
|
+
422: {
|
|
40
|
+
type: "validation";
|
|
41
|
+
on: string;
|
|
42
|
+
summary?: string;
|
|
43
|
+
message?: string;
|
|
44
|
+
found?: unknown;
|
|
45
|
+
property?: string;
|
|
46
|
+
expected?: string;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
} & {
|
|
52
|
+
[x: string]: {
|
|
53
|
+
post: {
|
|
54
|
+
body: {
|
|
55
|
+
RelayState?: string | undefined;
|
|
56
|
+
SAMLResponse: string;
|
|
57
|
+
};
|
|
58
|
+
params: {
|
|
59
|
+
organizationId: string;
|
|
60
|
+
};
|
|
61
|
+
query: unknown;
|
|
62
|
+
headers: unknown;
|
|
63
|
+
response: {
|
|
64
|
+
200: Response;
|
|
65
|
+
404: "No SAML connection is configured for this organization";
|
|
66
|
+
422: {
|
|
67
|
+
type: "validation";
|
|
68
|
+
on: string;
|
|
69
|
+
summary?: string;
|
|
70
|
+
message?: string;
|
|
71
|
+
found?: unknown;
|
|
72
|
+
property?: string;
|
|
73
|
+
expected?: string;
|
|
74
|
+
};
|
|
75
|
+
500: "SAML sign-in failed";
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
} & {
|
|
80
|
+
[x: string]: {
|
|
81
|
+
get: {
|
|
82
|
+
body: unknown;
|
|
83
|
+
params: {
|
|
84
|
+
organizationId: string;
|
|
85
|
+
};
|
|
86
|
+
query: unknown;
|
|
87
|
+
headers: unknown;
|
|
88
|
+
response: {
|
|
89
|
+
200: Response;
|
|
90
|
+
404: "No SAML connection is configured for this organization";
|
|
91
|
+
422: {
|
|
92
|
+
type: "validation";
|
|
93
|
+
on: string;
|
|
94
|
+
summary?: string;
|
|
95
|
+
message?: string;
|
|
96
|
+
found?: unknown;
|
|
97
|
+
property?: string;
|
|
98
|
+
expected?: string;
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
} & {
|
|
104
|
+
[x: string]: {
|
|
105
|
+
get: {
|
|
106
|
+
body: unknown;
|
|
107
|
+
params: {
|
|
108
|
+
organizationId: string;
|
|
109
|
+
};
|
|
110
|
+
query: unknown;
|
|
111
|
+
headers: unknown;
|
|
112
|
+
response: {
|
|
113
|
+
200: Response;
|
|
114
|
+
422: {
|
|
115
|
+
type: "validation";
|
|
116
|
+
on: string;
|
|
117
|
+
summary?: string;
|
|
118
|
+
message?: string;
|
|
119
|
+
found?: unknown;
|
|
120
|
+
property?: string;
|
|
121
|
+
expected?: string;
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
} & {
|
|
127
|
+
[x: string]: {
|
|
128
|
+
get: {
|
|
129
|
+
body: unknown;
|
|
130
|
+
params: {
|
|
131
|
+
organizationId: string;
|
|
132
|
+
};
|
|
133
|
+
query: {
|
|
134
|
+
RelayState?: string | undefined;
|
|
135
|
+
SAMLResponse?: string | undefined;
|
|
136
|
+
SAMLRequest?: string | undefined;
|
|
137
|
+
};
|
|
138
|
+
headers: unknown;
|
|
139
|
+
response: {
|
|
140
|
+
200: Response;
|
|
141
|
+
400: "Missing SAMLRequest or SAMLResponse" | "Invalid SAML LogoutRequest";
|
|
142
|
+
404: "No SAML connection is configured for this organization";
|
|
143
|
+
422: {
|
|
144
|
+
type: "validation";
|
|
145
|
+
on: string;
|
|
146
|
+
summary?: string;
|
|
147
|
+
message?: string;
|
|
148
|
+
found?: unknown;
|
|
149
|
+
property?: string;
|
|
150
|
+
expected?: string;
|
|
151
|
+
};
|
|
152
|
+
500: "SAML logout failed";
|
|
153
|
+
501: "SAML Single Logout is not configured";
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
}, {
|
|
158
|
+
derive: {};
|
|
159
|
+
resolve: {};
|
|
160
|
+
schema: {};
|
|
161
|
+
standaloneSchema: {};
|
|
162
|
+
response: {};
|
|
163
|
+
}, {
|
|
164
|
+
derive: {};
|
|
165
|
+
resolve: {};
|
|
166
|
+
schema: {};
|
|
167
|
+
standaloneSchema: {};
|
|
168
|
+
response: {};
|
|
169
|
+
} & {
|
|
170
|
+
derive: {};
|
|
171
|
+
resolve: {};
|
|
172
|
+
schema: {};
|
|
173
|
+
standaloneSchema: {};
|
|
174
|
+
response: {};
|
|
175
|
+
}>;
|
|
176
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { OrganizationId } from '../tenancy';
|
|
2
|
+
export type SSOConnectionType = 'oidc' | 'saml';
|
|
3
|
+
export type OidcConnectionConfig = {
|
|
4
|
+
clientId: string;
|
|
5
|
+
clientSecret: string;
|
|
6
|
+
issuer: string;
|
|
7
|
+
redirectUri: string;
|
|
8
|
+
scopes: string[];
|
|
9
|
+
};
|
|
10
|
+
export type SamlConnectionConfig = {
|
|
11
|
+
idpEntityId: string;
|
|
12
|
+
idpSloUrl?: string;
|
|
13
|
+
idpSsoUrl: string;
|
|
14
|
+
idpX509Cert: string;
|
|
15
|
+
};
|
|
16
|
+
type SSOConnectionBase = {
|
|
17
|
+
connectionId: string;
|
|
18
|
+
createdAt: number;
|
|
19
|
+
enabled: boolean;
|
|
20
|
+
organizationId: OrganizationId;
|
|
21
|
+
updatedAt: number;
|
|
22
|
+
};
|
|
23
|
+
export type OidcConnection = SSOConnectionBase & {
|
|
24
|
+
config: OidcConnectionConfig;
|
|
25
|
+
type: 'oidc';
|
|
26
|
+
};
|
|
27
|
+
export type SamlConnection = SSOConnectionBase & {
|
|
28
|
+
config: SamlConnectionConfig;
|
|
29
|
+
type: 'saml';
|
|
30
|
+
};
|
|
31
|
+
export type SSOConnection = OidcConnection | SamlConnection;
|
|
32
|
+
export type SSOConnectionStore = {
|
|
33
|
+
deleteConnection: (connectionId: string) => Promise<void>;
|
|
34
|
+
getConnection: (connectionId: string) => Promise<SSOConnection | undefined>;
|
|
35
|
+
getConnectionByOrganization: (organizationId: OrganizationId, type?: SSOConnectionType) => Promise<SSOConnection | undefined>;
|
|
36
|
+
listConnectionsByOrganization: (organizationId: OrganizationId) => Promise<SSOConnection[]>;
|
|
37
|
+
saveConnection: (connection: SSOConnection) => Promise<void>;
|
|
38
|
+
};
|
|
39
|
+
export {};
|
package/dist/typebox.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const authClientOption: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
2
2
|
export declare const authIntentOption: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"login">, import("@sinclair/typebox").TLiteral<"link_identity">, import("@sinclair/typebox").TLiteral<"link_connector">]>>;
|
|
3
3
|
export declare const authProviderOption: import("@sinclair/typebox").TEnum<{
|
|
4
|
-
[k: string]: "42" | "amazoncognito" | "anilist" | "apple" | "atlassian" | "auth0" | "authentik" | "autodesk" | "battlenet" | "bitbucket" | "box" | "bungie" | "coinbase" | "discord" | "donationalerts" | "dribbble" | "dropbox" | "epicgames" | "etsy" | "facebook" | "figma" | "gitea" | "github" | "gitlab" | "google" | "intuit" | "kakao" | "keycloak" | "kick" | "lichess" | "line" | "linear" | "linkedin" | "mastodon" | "mercadolibre" | "mercadopago" | "microsoftentraid" | "myanimelist" | "naver" | "notion" | "okta" | "osu" | "patreon" | "polar" | "polaraccesslink" | "polarteampro" | "reddit" | "roblox" | "salesforce" | "shikimori" | "slack" | "spotify" | "startgg" | "strava" | "synology" | "tiktok" | "tiltify" | "tumblr" | "twitch" | "twitter" | "vk" | "withings" | "workos" | "yahoo" | "yandex" | "zoom";
|
|
4
|
+
[k: string]: "42" | "amazoncognito" | "anilist" | "apple" | "atlassian" | "attio" | "auth0" | "authentik" | "autodesk" | "battlenet" | "bitbucket" | "box" | "bungie" | "close" | "coinbase" | "discord" | "donationalerts" | "dribbble" | "dropbox" | "epicgames" | "etsy" | "facebook" | "figma" | "gitea" | "github" | "gitlab" | "gohighlevel" | "google" | "hubspot" | "intuit" | "kakao" | "keycloak" | "kick" | "lichess" | "line" | "linear" | "linkedin" | "mastodon" | "mercadolibre" | "mercadopago" | "microsoftentraid" | "monday" | "myanimelist" | "naver" | "notion" | "okta" | "osu" | "patreon" | "pipedrive" | "polar" | "polaraccesslink" | "polarteampro" | "reddit" | "roblox" | "salesforce" | "shikimori" | "slack" | "spotify" | "startgg" | "strava" | "synology" | "tiktok" | "tiltify" | "tumblr" | "twitch" | "twitter" | "vk" | "withings" | "workos" | "yahoo" | "yandex" | "zoho" | "zoom";
|
|
5
5
|
}>;
|
|
6
6
|
export declare const userSessionIdTypebox: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TTemplateLiteralSyntax<"${string}-${string}-${string}-${string}-${string}">>;
|
package/dist/types.d.ts
CHANGED
|
@@ -2,13 +2,22 @@ import { CredentialsFor, NonEmptyArray, OAuth2Client, OAuth2TokenResponse, Provi
|
|
|
2
2
|
import { Cookie, status as statusType, redirect as redirectType } from 'elysia';
|
|
3
3
|
import { ElysiaCustomStatusResponse } from 'elysia/error';
|
|
4
4
|
import type { AuditConfig } from './audit/config';
|
|
5
|
+
import type { AuthorizationConfig } from './authorization/config';
|
|
6
|
+
import type { ComplianceConfig } from './compliance/config';
|
|
5
7
|
import type { CredentialsConfig } from './credentials/config';
|
|
6
8
|
import type { AuthIdentityConflict } from './errors';
|
|
7
9
|
import type { AuthHtmxConfig, AuthHtmxUser } from './htmx/types';
|
|
8
10
|
import type { LockoutConfig } from './lockout/config';
|
|
9
11
|
import type { MfaConfig } from './mfa/config';
|
|
12
|
+
import type { OrganizationsConfig } from './organizations/config';
|
|
13
|
+
import type { PasswordlessConfig } from './passwordless/config';
|
|
14
|
+
import type { RolesConfig } from './roles/config';
|
|
15
|
+
import type { ScimConfig } from './scim/config';
|
|
10
16
|
import type { SessionsConfig } from './session/sessionsConfig';
|
|
11
17
|
import type { AuthSessionStore } from './session/types';
|
|
18
|
+
import type { SSOConfig } from './sso/config';
|
|
19
|
+
import type { WebAuthnConfig } from './webauthn/config';
|
|
20
|
+
import type { WebhooksConfig } from './webhooks/config';
|
|
12
21
|
export type AuthIntent = 'login' | 'link_identity' | 'link_connector';
|
|
13
22
|
export type OAuth2ProviderClientConfiguration<Provider extends ProviderOption> = {
|
|
14
23
|
credentials: CredentialsFor<Provider>;
|
|
@@ -34,6 +43,14 @@ export type SessionData<UserType> = {
|
|
|
34
43
|
/** When the session was last established by an actual authentication (login, OAuth
|
|
35
44
|
* callback, or MFA challenge — NOT a token refresh). Drives step-up `requireRecentAuth`. */
|
|
36
45
|
authenticatedAt?: number;
|
|
46
|
+
/** SAML SP-initiated Single Logout context, captured at the SAML ACS. Lets
|
|
47
|
+
* `{ssoRoute}/saml/:org/logout` build a signed LogoutRequest (the IdP needs the original
|
|
48
|
+
* NameID + SessionIndex) for the connection the session was created from. */
|
|
49
|
+
samlLogout?: {
|
|
50
|
+
connectionId: string;
|
|
51
|
+
nameId: string;
|
|
52
|
+
sessionIndex?: string;
|
|
53
|
+
};
|
|
37
54
|
};
|
|
38
55
|
export type SessionRecord<UserType> = Record<UserSessionId, SessionData<UserType>>;
|
|
39
56
|
export type UnregisteredSessionData = {
|
|
@@ -170,6 +187,11 @@ export type AuthConfig<UserType> = {
|
|
|
170
187
|
* mounts register / verify-email / login / reset-password routes that produce the
|
|
171
188
|
* same `SessionData<UserType>` as OAuth, transparent to `protectRoute`. */
|
|
172
189
|
credentials?: CredentialsConfig<UserType>;
|
|
190
|
+
/** Passwordless login: magic links + email/SMS OTP. When present, mounts the magic-link flow
|
|
191
|
+
* (if `onSendMagicLink` is set) and/or the OTP flow (if `onSendOtp` is set) under
|
|
192
|
+
* `{passwordlessRoute}`; each verify route resolves the email to a user and mints the same
|
|
193
|
+
* `SessionData<UserType>` as every other flow. */
|
|
194
|
+
passwordless?: PasswordlessConfig<UserType>;
|
|
173
195
|
/** Multi-factor auth (TOTP + backup codes). When present alongside `credentials`,
|
|
174
196
|
* `auth()` auto-wires the login MFA gate, mounts the enroll/challenge routes, and
|
|
175
197
|
* promotes the parked session once a factor is verified. */
|
|
@@ -181,6 +203,43 @@ export type AuthConfig<UserType> = {
|
|
|
181
203
|
* sessions) and `DELETE /auth/sessions/:id` (remote revoke). Requires an
|
|
182
204
|
* `authSessionStore` that can enumerate sessions. */
|
|
183
205
|
sessions?: SessionsConfig<UserType>;
|
|
206
|
+
/** Per-organization enterprise SSO (the WorkOS-style model). When present, mounts
|
|
207
|
+
* `GET {ssoRoute}/oidc/:organizationId/authorize` + `.../callback`, resolves the org's
|
|
208
|
+
* OIDC connection from `ssoConnectionStore`, verifies the id_token in-house against the
|
|
209
|
+
* issuer's JWKS, and mints the same `SessionData<UserType>` as every other flow. */
|
|
210
|
+
sso?: SSOConfig<UserType>;
|
|
211
|
+
/** SCIM 2.0 auto-provisioning for enterprise directory sync (Okta / Azure AD). When present,
|
|
212
|
+
* mounts `{scimRoute}/Users` (+ `/ServiceProviderConfig`) with per-org bearer-token auth via
|
|
213
|
+
* `scimTokenStore`, and maps SCIM resources to the consumer's user store through hooks. */
|
|
214
|
+
scim?: ScimConfig;
|
|
215
|
+
/** First-class multi-tenancy (the WorkOS model). When present, mounts organization +
|
|
216
|
+
* membership + invitation routes under `{organizationsRoute}`: list the caller's orgs, create
|
|
217
|
+
* one (caller becomes owner), invite/accept/revoke by email, and list/remove members. Ties the
|
|
218
|
+
* bare `organizationId` used by SSO/SCIM/RBAC into a real tenant model with org-scoped roles. */
|
|
219
|
+
organizations?: OrganizationsConfig<UserType>;
|
|
220
|
+
/** Org-scoped roles & permissions (builds on `organizations`). When present, mounts routes to
|
|
221
|
+
* list an org's role definitions and set a member's roles. Pair with
|
|
222
|
+
* `createMembershipPermissionResolver` to make `authorization.hasPermission` turnkey. */
|
|
223
|
+
roles?: RolesConfig<UserType>;
|
|
224
|
+
/** Role-based / attribute-based access control (E4). When present, `auth()` exposes a
|
|
225
|
+
* `protectPermission(check, handler)` derive (alongside `protectRoute`) that delegates the
|
|
226
|
+
* decision to your `hasPermission` hook — the package stays schema-agnostic about roles. */
|
|
227
|
+
authorization?: AuthorizationConfig<UserType>;
|
|
228
|
+
/** GDPR/CCPA self-service compliance (E5). When present, mounts `GET {complianceRoute}/export`
|
|
229
|
+
* (right to access) and `DELETE {complianceRoute}` (right to erasure — runs your delete hook,
|
|
230
|
+
* revokes the user's sessions, clears the cookie). Pair with `audit.redact` for PII redaction. */
|
|
231
|
+
compliance?: ComplianceConfig<UserType>;
|
|
232
|
+
/** Passwordless / passkey auth (WebAuthn). When present, mounts the registration ceremony
|
|
233
|
+
* (`{webauthnRoute}/register/options` + `/verify`, adds a passkey to the authenticated caller)
|
|
234
|
+
* and the authentication ceremony (`.../authenticate/options` + `/verify`, passwordless sign-in
|
|
235
|
+
* → mints the same `SessionData<UserType>`). A `webauthnAdapter` wraps a vetted library (e.g.
|
|
236
|
+
* `@simplewebauthn/server`); the package never bundles the WebAuthn crypto. */
|
|
237
|
+
webauthn?: WebAuthnConfig<UserType>;
|
|
238
|
+
/** Signed outbound webhooks. When present, every emitted auth event (the audit taxonomy) is
|
|
239
|
+
* HMAC-signed (Standard Webhooks scheme) and POSTed to each endpoint. Delivery is best-effort
|
|
240
|
+
* and isolated per endpoint; configuring this alone (without `audit`) is enough to turn on
|
|
241
|
+
* event emission. PII redaction (`audit.redact`) applies before delivery. */
|
|
242
|
+
webhooks?: WebhooksConfig;
|
|
184
243
|
/** Enable the built-in HTMX fragment routes (login, identities, connectors,
|
|
185
244
|
* account, signout, delete-account). Supply provider display data + the
|
|
186
245
|
* identity/connector data actions; the package owns the route wiring and
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export type WebAuthnCredentialDescriptor = {
|
|
2
|
+
id: string;
|
|
3
|
+
transports?: string[];
|
|
4
|
+
};
|
|
5
|
+
export type WebAuthnRegistrationOptions = {
|
|
6
|
+
challenge: string;
|
|
7
|
+
options: Record<string, unknown>;
|
|
8
|
+
};
|
|
9
|
+
export type WebAuthnAuthenticationOptions = {
|
|
10
|
+
challenge: string;
|
|
11
|
+
options: Record<string, unknown>;
|
|
12
|
+
};
|
|
13
|
+
export type WebAuthnRegistrationResult = {
|
|
14
|
+
credential?: {
|
|
15
|
+
backedUp?: boolean;
|
|
16
|
+
counter: number;
|
|
17
|
+
credentialId: string;
|
|
18
|
+
deviceType?: string;
|
|
19
|
+
publicKey: string;
|
|
20
|
+
transports?: string[];
|
|
21
|
+
};
|
|
22
|
+
verified: boolean;
|
|
23
|
+
};
|
|
24
|
+
export type WebAuthnAuthenticationResult = {
|
|
25
|
+
newCounter?: number;
|
|
26
|
+
verified: boolean;
|
|
27
|
+
};
|
|
28
|
+
export type WebAuthnAdapter = {
|
|
29
|
+
createAuthenticationOptions: (request: {
|
|
30
|
+
allowCredentials: WebAuthnCredentialDescriptor[];
|
|
31
|
+
rpId: string;
|
|
32
|
+
}) => Promise<WebAuthnAuthenticationOptions> | WebAuthnAuthenticationOptions;
|
|
33
|
+
createRegistrationOptions: (request: {
|
|
34
|
+
excludeCredentials: WebAuthnCredentialDescriptor[];
|
|
35
|
+
rpId: string;
|
|
36
|
+
rpName: string;
|
|
37
|
+
userDisplayName: string;
|
|
38
|
+
userId: string;
|
|
39
|
+
userName: string;
|
|
40
|
+
}) => Promise<WebAuthnRegistrationOptions> | WebAuthnRegistrationOptions;
|
|
41
|
+
verifyAuthentication: (request: {
|
|
42
|
+
credential: {
|
|
43
|
+
counter: number;
|
|
44
|
+
credentialId: string;
|
|
45
|
+
publicKey: string;
|
|
46
|
+
transports?: string[];
|
|
47
|
+
};
|
|
48
|
+
expectedChallenge: string;
|
|
49
|
+
expectedOrigin: string;
|
|
50
|
+
expectedRPID: string;
|
|
51
|
+
response: unknown;
|
|
52
|
+
}) => Promise<WebAuthnAuthenticationResult>;
|
|
53
|
+
verifyRegistration: (request: {
|
|
54
|
+
expectedChallenge: string;
|
|
55
|
+
expectedOrigin: string;
|
|
56
|
+
expectedRPID: string;
|
|
57
|
+
response: unknown;
|
|
58
|
+
}) => Promise<WebAuthnRegistrationResult>;
|
|
59
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { AuditEmitter } from '../audit/config';
|
|
2
|
+
import type { AuthSessionStore } from '../session/types';
|
|
3
|
+
import type { RouteString, UserSessionId } from '../types';
|
|
4
|
+
import type { WebAuthnAdapter } from './adapter';
|
|
5
|
+
import type { WebAuthnCredentialStore } from './types';
|
|
6
|
+
export declare const DEFAULT_WEBAUTHN_CHALLENGE_TTL_MS = 300000;
|
|
7
|
+
export declare const DEFAULT_WEBAUTHN_ROUTE: RouteString;
|
|
8
|
+
export declare const DEFAULT_WEBAUTHN_SESSION_TTL_MS: number;
|
|
9
|
+
export declare const WEBAUTHN_CHALLENGE_COOKIE = "webauthn_challenge";
|
|
10
|
+
export type WebAuthnConfig<UserType> = {
|
|
11
|
+
credentialStore: WebAuthnCredentialStore;
|
|
12
|
+
getUserId: (user: UserType) => string;
|
|
13
|
+
getWebAuthnUser: (userId: string) => Promise<UserType | null | undefined> | UserType | null | undefined;
|
|
14
|
+
origin: string;
|
|
15
|
+
rpId: string;
|
|
16
|
+
rpName: string;
|
|
17
|
+
webauthnAdapter: WebAuthnAdapter;
|
|
18
|
+
challengeDurationMs?: number;
|
|
19
|
+
getUserDisplayName?: (user: UserType) => string;
|
|
20
|
+
getUserName?: (user: UserType) => string;
|
|
21
|
+
onWebAuthnAuthenticated?: (context: {
|
|
22
|
+
user: UserType;
|
|
23
|
+
userSessionId: UserSessionId;
|
|
24
|
+
}) => void | Promise<void>;
|
|
25
|
+
onWebAuthnRegistered?: (context: {
|
|
26
|
+
credentialId: string;
|
|
27
|
+
userId: string;
|
|
28
|
+
}) => void | Promise<void>;
|
|
29
|
+
sessionDurationMs?: number;
|
|
30
|
+
webauthnRoute?: RouteString;
|
|
31
|
+
};
|
|
32
|
+
export type WebAuthnRouteProps<UserType> = WebAuthnConfig<UserType> & {
|
|
33
|
+
authSessionStore?: AuthSessionStore<UserType>;
|
|
34
|
+
emit?: AuditEmitter;
|
|
35
|
+
};
|