@revojs/auth 0.2.8 → 0.2.9
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/index.d.ts +167 -16
- package/dist/index.js +232 -33
- package/dist/module/index.d.ts +1 -0
- package/dist/module/index.js +55 -52
- package/dist/organization/routes/auth/invitations/accept/post.d.ts +4 -0
- package/dist/organization/routes/auth/invitations/accept/post.js +46 -0
- package/dist/organization/routes/auth/organizations/[organizationId]/get.d.ts +4 -0
- package/dist/organization/routes/auth/organizations/[organizationId]/get.js +14 -0
- package/dist/organization/routes/auth/organizations/[organizationId]/invitations/[invitationId]/delete.d.ts +4 -0
- package/dist/organization/routes/auth/organizations/[organizationId]/invitations/[invitationId]/delete.js +34 -0
- package/dist/organization/routes/auth/organizations/[organizationId]/invitations/get.d.ts +4 -0
- package/dist/organization/routes/auth/organizations/[organizationId]/invitations/get.js +22 -0
- package/dist/organization/routes/auth/organizations/[organizationId]/invitations/post.d.ts +4 -0
- package/dist/organization/routes/auth/organizations/[organizationId]/invitations/post.js +56 -0
- package/dist/organization/routes/auth/organizations/[organizationId]/memberships/[membershipId]/delete.d.ts +4 -0
- package/dist/organization/routes/auth/organizations/[organizationId]/memberships/[membershipId]/delete.js +30 -0
- package/dist/organization/routes/auth/organizations/[organizationId]/memberships/[membershipId]/patch.d.ts +4 -0
- package/dist/organization/routes/auth/organizations/[organizationId]/memberships/[membershipId]/patch.js +35 -0
- package/dist/organization/routes/auth/organizations/[organizationId]/memberships/get.d.ts +4 -0
- package/dist/organization/routes/auth/organizations/[organizationId]/memberships/get.js +14 -0
- package/dist/organization/routes/auth/organizations/[organizationId]/ownership/post.d.ts +4 -0
- package/dist/organization/routes/auth/organizations/[organizationId]/ownership/post.js +38 -0
- package/dist/organization/routes/auth/organizations/[organizationId]/patch.d.ts +4 -0
- package/dist/organization/routes/auth/organizations/[organizationId]/patch.js +36 -0
- package/dist/organization/routes/auth/organizations/[organizationId]/traces/get.d.ts +4 -0
- package/dist/organization/routes/auth/organizations/[organizationId]/traces/get.js +26 -0
- package/dist/organization/routes/auth/organizations/get.d.ts +4 -0
- package/dist/organization/routes/auth/organizations/get.js +11 -0
- package/dist/organization/routes/auth/organizations/post.d.ts +4 -0
- package/dist/organization/routes/auth/organizations/post.js +40 -0
- package/dist/routes/auth/+middleware.d.ts +4 -0
- package/dist/routes/auth/+middleware.js +9 -0
- package/dist/routes/auth/sessions/delete.js +2 -3
- package/dist/routes/auth/sessions/get.js +3 -5
- package/dist/routes/auth/sessions/post.js +4 -6
- package/dist/storage/mysql.d.ts +272 -0
- package/dist/storage/mysql.js +184 -0
- package/dist/storage/postgresql.d.ts +272 -0
- package/dist/storage/postgresql.js +184 -0
- package/dist/storage/sqlite.d.ts +272 -0
- package/dist/storage/sqlite.js +184 -0
- package/package.json +15 -1
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,60 @@ export type PasskeyMethod = InferInput<typeof passkeyMethodSchema>;
|
|
|
8
8
|
export type ProviderMethod = InferInput<typeof providerMethodSchema>;
|
|
9
9
|
export type Method = InferInput<typeof methodSchema>;
|
|
10
10
|
export type Providers = "apple" | "github" | "google" | "microsoft";
|
|
11
|
+
export type MembershipStatus = "active" | "suspended";
|
|
12
|
+
export type InvitationStatus = "pending" | "accepted" | "revoked";
|
|
13
|
+
export type TraceAction = "organization.create" | "organization.update" | "organization.transferOwnership" | "membership.active" | "membership.suspended" | "membership.remove" | "invitation.create" | "invitation.accept" | "invitation.revoke";
|
|
14
|
+
export type TraceCursor = Pick<Trace, "createdAt" | "id">;
|
|
15
|
+
export type AuthStorage = AccountStorage & OrganizationStorage;
|
|
16
|
+
export interface Account {
|
|
17
|
+
id: string;
|
|
18
|
+
email: string;
|
|
19
|
+
password: string | null;
|
|
20
|
+
createdAt: Date;
|
|
21
|
+
}
|
|
22
|
+
export interface Identity {
|
|
23
|
+
id: string;
|
|
24
|
+
provider: string;
|
|
25
|
+
credential: string;
|
|
26
|
+
createdAt: Date;
|
|
27
|
+
accountId: string;
|
|
28
|
+
}
|
|
29
|
+
export interface Session {
|
|
30
|
+
id: string;
|
|
31
|
+
createdAt: Date;
|
|
32
|
+
accountId: string;
|
|
33
|
+
}
|
|
34
|
+
export interface AccountStorage {
|
|
35
|
+
getAccountByEmail: (email: string) => Promise<Account | undefined>;
|
|
36
|
+
getAccountById: (id: string) => Promise<Account | undefined>;
|
|
37
|
+
createAccount: (account: Account) => Promise<Account | undefined>;
|
|
38
|
+
deleteAccount: (id: string) => Promise<void>;
|
|
39
|
+
getIdentity: (provider: string, credential: string) => Promise<Identity | undefined>;
|
|
40
|
+
createIdentity: (identity: Identity) => Promise<Identity | undefined>;
|
|
41
|
+
getSession: (id: string, accountId: string) => Promise<Session | undefined>;
|
|
42
|
+
createSession: (session: Session) => Promise<Session | undefined>;
|
|
43
|
+
deleteSession: (id: string, accountId: string) => Promise<void>;
|
|
44
|
+
}
|
|
45
|
+
export interface OrganizationStorage {
|
|
46
|
+
transaction: <T>(run: (storage: AuthStorage) => Promise<T>) => Promise<T>;
|
|
47
|
+
getOrganization: (id: string) => Promise<Organization | undefined>;
|
|
48
|
+
listOrganizations: (accountId: string) => Promise<Array<Organization>>;
|
|
49
|
+
createOrganization: (organization: Organization) => Promise<void>;
|
|
50
|
+
updateOrganization: (id: string, values: Pick<Organization, "name" | "accountId">) => Promise<void>;
|
|
51
|
+
getMembership: (organizationId: string, accountId: string) => Promise<Membership | undefined>;
|
|
52
|
+
getMembershipById: (organizationId: string, id: string) => Promise<Membership | undefined>;
|
|
53
|
+
listMemberships: (organizationId: string) => Promise<Array<Membership>>;
|
|
54
|
+
createMembership: (membership: Membership) => Promise<void>;
|
|
55
|
+
updateMembership: (organizationId: string, id: string, status: MembershipStatus) => Promise<void>;
|
|
56
|
+
deleteMembership: (organizationId: string, id: string) => Promise<void>;
|
|
57
|
+
getInvitation: (organizationId: string, id: string) => Promise<Invitation | undefined>;
|
|
58
|
+
getInvitationByHash: (hash: string) => Promise<Invitation | undefined>;
|
|
59
|
+
listInvitations: (organizationId: string) => Promise<Array<Invitation>>;
|
|
60
|
+
createInvitation: (invitation: Invitation) => Promise<void>;
|
|
61
|
+
updateInvitation: (organizationId: string, id: string, status: InvitationStatus) => Promise<void>;
|
|
62
|
+
createTrace: (trace: Trace) => Promise<void>;
|
|
63
|
+
listTraces: (organizationId: string, limit: number, before?: TraceCursor) => Promise<Array<Trace>>;
|
|
64
|
+
}
|
|
11
65
|
export interface Token {
|
|
12
66
|
access_token: string;
|
|
13
67
|
token_type: string;
|
|
@@ -50,28 +104,125 @@ export interface AuthProviderOptions {
|
|
|
50
104
|
export interface AuthProvider {
|
|
51
105
|
setup: (scope: Scope) => AuthProviderOptions;
|
|
52
106
|
}
|
|
53
|
-
export
|
|
107
|
+
export interface Organization {
|
|
108
|
+
id: string;
|
|
109
|
+
name: string;
|
|
110
|
+
accountId: string;
|
|
111
|
+
createdAt: Date;
|
|
112
|
+
}
|
|
113
|
+
export interface Membership {
|
|
114
|
+
id: string;
|
|
115
|
+
organizationId: string;
|
|
116
|
+
accountId: string;
|
|
117
|
+
status: MembershipStatus;
|
|
118
|
+
createdAt: Date;
|
|
119
|
+
}
|
|
120
|
+
export interface Invitation {
|
|
121
|
+
id: string;
|
|
122
|
+
organizationId: string;
|
|
123
|
+
email: string;
|
|
124
|
+
tokenHash: string;
|
|
125
|
+
invitedBy: string;
|
|
126
|
+
status: InvitationStatus;
|
|
127
|
+
expiresAt: Date;
|
|
128
|
+
createdAt: Date;
|
|
129
|
+
}
|
|
130
|
+
export interface Trace {
|
|
131
|
+
id: string;
|
|
132
|
+
organizationId: string;
|
|
133
|
+
accountId: string;
|
|
134
|
+
action: TraceAction;
|
|
135
|
+
subjectId: string;
|
|
136
|
+
content: string;
|
|
137
|
+
createdAt: Date;
|
|
138
|
+
}
|
|
139
|
+
export declare function useClientAuth(scope: Scope): {
|
|
54
140
|
signInWithCredentials(credential: PasswordMethod | PasskeyMethod): Promise<unknown>;
|
|
55
141
|
signInWithProvider(provider: Providers | (string & {}), redirectUrl: string): Promise<void>;
|
|
56
142
|
signOut(): Promise<unknown>;
|
|
57
143
|
};
|
|
58
|
-
export declare function requireSession
|
|
144
|
+
export declare function requireSession(scope: Scope, redirectUrl?: string): Promise<Session>;
|
|
59
145
|
export declare function getCryptoKey(scope: Scope): Promise<CryptoKey>;
|
|
60
|
-
export declare function getSession
|
|
61
|
-
export declare function setSession
|
|
146
|
+
export declare function getSession(scope: Scope): Promise<Session | undefined>;
|
|
147
|
+
export declare function setSession(scope: Scope, session: Session): Promise<void>;
|
|
62
148
|
export declare function clearSession(scope: Scope): void;
|
|
63
149
|
export declare function defineAuthProvider(provider: AuthProvider): Route;
|
|
64
|
-
export declare
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
150
|
+
export declare function useServerAuth(scope: Scope): Promise<{
|
|
151
|
+
getAccountByEmail: (email: string) => Promise<Account | undefined>;
|
|
152
|
+
getAccountById: (id: string) => Promise<Account | undefined>;
|
|
153
|
+
createAccount: (account: Account) => Promise<Account | undefined>;
|
|
154
|
+
deleteAccount: (id: string) => Promise<void>;
|
|
155
|
+
getIdentity: (provider: string, credential: string) => Promise<Identity | undefined>;
|
|
156
|
+
createIdentity: (identity: Identity) => Promise<Identity | undefined>;
|
|
157
|
+
getSession: (id: string, accountId: string) => Promise<Session | undefined>;
|
|
158
|
+
createSession: (session: Session) => Promise<Session | undefined>;
|
|
159
|
+
deleteSession: (id: string, accountId: string) => Promise<void>;
|
|
160
|
+
transaction: <T>(run: (storage: AuthStorage) => Promise<T>) => Promise<T>;
|
|
161
|
+
getOrganization: (id: string) => Promise<Organization | undefined>;
|
|
162
|
+
listOrganizations: (accountId: string) => Promise<Array<Organization>>;
|
|
163
|
+
createOrganization: (organization: Organization) => Promise<void>;
|
|
164
|
+
updateOrganization: (id: string, values: Pick<Organization, "name" | "accountId">) => Promise<void>;
|
|
165
|
+
getMembership: (organizationId: string, accountId: string) => Promise<Membership | undefined>;
|
|
166
|
+
getMembershipById: (organizationId: string, id: string) => Promise<Membership | undefined>;
|
|
167
|
+
listMemberships: (organizationId: string) => Promise<Array<Membership>>;
|
|
168
|
+
createMembership: (membership: Membership) => Promise<void>;
|
|
169
|
+
updateMembership: (organizationId: string, id: string, status: MembershipStatus) => Promise<void>;
|
|
170
|
+
deleteMembership: (organizationId: string, id: string) => Promise<void>;
|
|
171
|
+
getInvitation: (organizationId: string, id: string) => Promise<Invitation | undefined>;
|
|
172
|
+
getInvitationByHash: (hash: string) => Promise<Invitation | undefined>;
|
|
173
|
+
listInvitations: (organizationId: string) => Promise<Array<Invitation>>;
|
|
174
|
+
createInvitation: (invitation: Invitation) => Promise<void>;
|
|
175
|
+
updateInvitation: (organizationId: string, id: string, status: InvitationStatus) => Promise<void>;
|
|
176
|
+
createTrace: (trace: Trace) => Promise<void>;
|
|
177
|
+
listTraces: (organizationId: string, limit: number, before?: TraceCursor) => Promise<Array<Trace>>;
|
|
178
|
+
}>;
|
|
179
|
+
export declare function useAccountStorage(scope: Scope): Promise<AccountStorage>;
|
|
180
|
+
export declare function useOrganizationStorage(scope: Scope): Promise<OrganizationStorage>;
|
|
181
|
+
export declare function getPrincipal(scope: Scope, method: Method): Promise<Principal | false | undefined>;
|
|
182
|
+
export declare function createPrincipal(scope: Scope, method: Method): Promise<Principal | undefined>;
|
|
183
|
+
export declare function createSession(scope: Scope, principal: Principal): Promise<Session | undefined>;
|
|
184
|
+
export declare const authIdSchema: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 128, undefined>]>;
|
|
185
|
+
export declare const organizationNameSchema: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MaxLengthAction<string, 200, undefined>, import("valibot").TrimAction, import("valibot").MinLengthAction<string, 1, undefined>]>;
|
|
186
|
+
export declare const organizationParametersSchema: import("valibot").ObjectSchema<{
|
|
187
|
+
readonly organizationId: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 128, undefined>]>;
|
|
188
|
+
}, undefined>;
|
|
189
|
+
export declare const membershipParametersSchema: import("valibot").ObjectSchema<{
|
|
190
|
+
readonly organizationId: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 128, undefined>]>;
|
|
191
|
+
readonly membershipId: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 1, undefined>, import("valibot").MaxLengthAction<string, 128, undefined>]>;
|
|
192
|
+
}, undefined>;
|
|
193
|
+
export declare const BEFORE_PRINCIPAL_GET_HOOK: import("revojs").Descriptor<(method: Readonly<Method>) => Awaitable<void | boolean>>;
|
|
194
|
+
export declare const AFTER_PRINCIPAL_GET_HOOK: import("revojs").Descriptor<(principal: Readonly<Principal>, method: Readonly<Method>) => Awaitable<void>>;
|
|
195
|
+
export declare const BEFORE_PRINCIPAL_CREATE_HOOK: import("revojs").Descriptor<(method: Readonly<Method>) => Awaitable<void | boolean>>;
|
|
196
|
+
export declare const AFTER_PRINCIPAL_CREATE_HOOK: import("revojs").Descriptor<(principal: Readonly<Principal>, method: Readonly<Method>) => Awaitable<void>>;
|
|
197
|
+
export declare const BEFORE_ACCOUNT_GET_HOOK: import("revojs").Descriptor<(field: "id" | "email", value: string) => Awaitable<void | boolean>>;
|
|
198
|
+
export declare const AFTER_ACCOUNT_GET_HOOK: import("revojs").Descriptor<(account: Readonly<Account>) => Awaitable<void>>;
|
|
199
|
+
export declare const BEFORE_IDENTITY_GET_HOOK: import("revojs").Descriptor<(provider: string, credential: string) => Awaitable<void | boolean>>;
|
|
200
|
+
export declare const AFTER_IDENTITY_GET_HOOK: import("revojs").Descriptor<(identity: Readonly<Identity>) => Awaitable<void>>;
|
|
201
|
+
export declare const BEFORE_SESSION_GET_HOOK: import("revojs").Descriptor<(id: string, accountId: string) => Awaitable<void | boolean>>;
|
|
202
|
+
export declare const AFTER_SESSION_GET_HOOK: import("revojs").Descriptor<(session: Readonly<Session>) => Awaitable<void>>;
|
|
203
|
+
export declare const BEFORE_ACCOUNT_CREATE_HOOK: import("revojs").Descriptor<(account: Readonly<Account>, method: Readonly<Method>) => Awaitable<void | boolean | Record<string, unknown>>>;
|
|
204
|
+
export declare const AFTER_ACCOUNT_CREATE_HOOK: import("revojs").Descriptor<(account: Readonly<Account>) => Awaitable<void>>;
|
|
205
|
+
export declare const BEFORE_IDENTITY_CREATE_HOOK: import("revojs").Descriptor<(identity: Readonly<Identity>, method: Readonly<Method>) => Awaitable<void | boolean | Record<string, unknown>>>;
|
|
206
|
+
export declare const AFTER_IDENTITY_CREATE_HOOK: import("revojs").Descriptor<(identity: Readonly<Identity>) => Awaitable<void>>;
|
|
207
|
+
export declare const BEFORE_SESSION_CREATE_HOOK: import("revojs").Descriptor<(session: Readonly<Session>, principal: Readonly<Principal>) => Awaitable<void | boolean | Record<string, unknown>>>;
|
|
208
|
+
export declare const AFTER_SESSION_CREATE_HOOK: import("revojs").Descriptor<(session: Readonly<Session>) => Awaitable<void>>;
|
|
69
209
|
export declare const registerAuthHooks: (scope: Scope, hooks: Partial<import("revojs").Hooks<{
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
210
|
+
beforePrincipalGet: import("revojs").Descriptor<(method: Readonly<Method>) => Awaitable<void | boolean>>;
|
|
211
|
+
afterPrincipalGet: import("revojs").Descriptor<(principal: Readonly<Principal>, method: Readonly<Method>) => Awaitable<void>>;
|
|
212
|
+
beforePrincipalCreate: import("revojs").Descriptor<(method: Readonly<Method>) => Awaitable<void | boolean>>;
|
|
213
|
+
afterPrincipalCreate: import("revojs").Descriptor<(principal: Readonly<Principal>, method: Readonly<Method>) => Awaitable<void>>;
|
|
214
|
+
beforeAccountGet: import("revojs").Descriptor<(field: "id" | "email", value: string) => Awaitable<void | boolean>>;
|
|
215
|
+
afterAccountGet: import("revojs").Descriptor<(account: Readonly<Account>) => Awaitable<void>>;
|
|
216
|
+
beforeIdentityGet: import("revojs").Descriptor<(provider: string, credential: string) => Awaitable<void | boolean>>;
|
|
217
|
+
afterIdentityGet: import("revojs").Descriptor<(identity: Readonly<Identity>) => Awaitable<void>>;
|
|
218
|
+
beforeSessionGet: import("revojs").Descriptor<(id: string, accountId: string) => Awaitable<void | boolean>>;
|
|
219
|
+
afterSessionGet: import("revojs").Descriptor<(session: Readonly<Session>) => Awaitable<void>>;
|
|
220
|
+
beforeAccountCreate: import("revojs").Descriptor<(account: Readonly<Account>, method: Readonly<Method>) => Awaitable<void | boolean | Record<string, unknown>>>;
|
|
221
|
+
afterAccountCreate: import("revojs").Descriptor<(account: Readonly<Account>) => Awaitable<void>>;
|
|
222
|
+
beforeIdentityCreate: import("revojs").Descriptor<(identity: Readonly<Identity>, method: Readonly<Method>) => Awaitable<void | boolean | Record<string, unknown>>>;
|
|
223
|
+
afterIdentityCreate: import("revojs").Descriptor<(identity: Readonly<Identity>) => Awaitable<void>>;
|
|
224
|
+
beforeSessionCreate: import("revojs").Descriptor<(session: Readonly<Session>, principal: Readonly<Principal>) => Awaitable<void | boolean | Record<string, unknown>>>;
|
|
225
|
+
afterSessionCreate: import("revojs").Descriptor<(session: Readonly<Session>) => Awaitable<void>>;
|
|
75
226
|
}>>) => void;
|
|
76
227
|
export declare const principalSchema: import("valibot").ObjectSchema<{
|
|
77
228
|
readonly sub: import("valibot").StringSchema<undefined>;
|
|
@@ -86,7 +237,7 @@ export declare const passwordMethodSchema: import("valibot").ObjectSchema<{
|
|
|
86
237
|
readonly type: import("valibot").LiteralSchema<"PASSWORD", undefined>;
|
|
87
238
|
readonly email: import("valibot").StringSchema<undefined>;
|
|
88
239
|
readonly password: import("valibot").StringSchema<undefined>;
|
|
89
|
-
readonly register: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>,
|
|
240
|
+
readonly register: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, false>;
|
|
90
241
|
}, undefined>;
|
|
91
242
|
export declare const passkeyMethodSchema: import("valibot").ObjectSchema<{
|
|
92
243
|
readonly type: import("valibot").LiteralSchema<"PASSKEY", undefined>;
|
|
@@ -109,7 +260,7 @@ export declare const methodSchema: import("valibot").UnionSchema<[import("valibo
|
|
|
109
260
|
readonly type: import("valibot").LiteralSchema<"PASSWORD", undefined>;
|
|
110
261
|
readonly email: import("valibot").StringSchema<undefined>;
|
|
111
262
|
readonly password: import("valibot").StringSchema<undefined>;
|
|
112
|
-
readonly register: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>,
|
|
263
|
+
readonly register: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, false>;
|
|
113
264
|
}, undefined>, import("valibot").ObjectSchema<{
|
|
114
265
|
readonly type: import("valibot").LiteralSchema<"PASSKEY", undefined>;
|
|
115
266
|
}, undefined>, import("valibot").ObjectSchema<{
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import config from "#config/auth";
|
|
2
2
|
import { isClient, isServer } from "#variables";
|
|
3
|
-
import { deleteCookie, fetch, sendForbidden, sendRedirect, setCookie, useCookies, useHeaders, useQuery, useUrl, withQuery } from "@revojs/server";
|
|
4
|
-
import {
|
|
3
|
+
import { deleteCookie, fetch, sendForbidden, sendRedirect, sendUnauthorized, setCookie, useCookies, useHeaders, useQuery, useUrl, withQuery } from "@revojs/server";
|
|
4
|
+
import { useStorageProvider } from "@revojs/storage";
|
|
5
|
+
import { createRegisterHooks, defineHook, dispatchHook, useVariables } from "revojs";
|
|
5
6
|
import { mergeObjects } from "revojs/shared";
|
|
6
|
-
import { boolean, literal, nullish, number, object, optional, parse, pipe, string, transform, union } from "valibot";
|
|
7
|
+
import { boolean, literal, maxLength, minLength, nullish, number, object, optional, parse, pipe, string, transform, trim, union } from "valibot";
|
|
7
8
|
//#region src/index.ts
|
|
8
|
-
function
|
|
9
|
+
function useClientAuth(scope) {
|
|
9
10
|
return {
|
|
10
11
|
async signInWithCredentials(credential) {
|
|
11
12
|
return await fetch(scope, `/auth/sessions`, {
|
|
@@ -23,21 +24,20 @@ function useAuth(scope) {
|
|
|
23
24
|
};
|
|
24
25
|
}
|
|
25
26
|
async function requireSession(scope, redirectUrl) {
|
|
26
|
-
if (isClient) {
|
|
27
|
+
if (isClient) try {
|
|
28
|
+
return await fetch(scope, "/auth/sessions", {
|
|
29
|
+
method: "GET",
|
|
30
|
+
headers: useHeaders(scope)
|
|
31
|
+
});
|
|
32
|
+
} catch (error) {
|
|
33
|
+
if (!redirectUrl) throw error;
|
|
27
34
|
const { pathname } = useUrl(scope);
|
|
28
|
-
|
|
29
|
-
return await fetch(scope, "/auth/sessions", {
|
|
30
|
-
method: "GET",
|
|
31
|
-
headers: useHeaders(scope)
|
|
32
|
-
});
|
|
33
|
-
} catch {
|
|
34
|
-
if (redirectUrl !== pathname) globalThis.location.href = redirectUrl;
|
|
35
|
-
}
|
|
35
|
+
if (redirectUrl !== pathname) globalThis.location.href = redirectUrl;
|
|
36
36
|
}
|
|
37
37
|
if (isServer) {
|
|
38
38
|
const session = await getSession(scope);
|
|
39
39
|
if (session) return session;
|
|
40
|
-
throw sendRedirect(scope, redirectUrl);
|
|
40
|
+
throw redirectUrl ? sendRedirect(scope, redirectUrl) : sendUnauthorized(scope);
|
|
41
41
|
}
|
|
42
42
|
throw new Error("Session is unavailable");
|
|
43
43
|
}
|
|
@@ -52,10 +52,21 @@ async function getSession(scope) {
|
|
|
52
52
|
const session = useCookies(scope)[config.session.name];
|
|
53
53
|
if (session) {
|
|
54
54
|
const index = session.lastIndexOf(".");
|
|
55
|
-
if (index > 0)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
if (index > 0) {
|
|
56
|
+
let value;
|
|
57
|
+
try {
|
|
58
|
+
const payload = session.slice(0, index);
|
|
59
|
+
if (await crypto.subtle.verify("HMAC", await getCryptoKey(scope), Uint8Array.fromBase64(session.slice(index + 1), BASE64_VERIFY), Uint8Array.fromBase64(payload, BASE64_VERIFY))) value = JSON.parse(decoder.decode(Uint8Array.fromBase64(payload, BASE64_VERIFY)));
|
|
60
|
+
} catch {}
|
|
61
|
+
if (value) {
|
|
62
|
+
if ((await dispatchHook(scope, BEFORE_SESSION_GET_HOOK, value.id, value.accountId)).includes(false)) return;
|
|
63
|
+
const session = await (await useAccountStorage(scope)).getSession(value.id, value.accountId);
|
|
64
|
+
if (session && Number.isFinite(session.createdAt.getTime()) && (config.session.cookie.maxAge === void 0 || Date.now() < session.createdAt.getTime() + config.session.cookie.maxAge * 1e3)) {
|
|
65
|
+
await dispatchHook(scope, AFTER_SESSION_GET_HOOK, session);
|
|
66
|
+
return session;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
59
70
|
}
|
|
60
71
|
}
|
|
61
72
|
async function setSession(scope, session) {
|
|
@@ -114,10 +125,9 @@ function defineAuthProvider(provider) {
|
|
|
114
125
|
...options.userInfo.headers
|
|
115
126
|
} }))
|
|
116
127
|
};
|
|
117
|
-
|
|
118
|
-
const principal = await dispatchHookSingle(scope, GET_PRINCIPAL_HOOK, method) ?? await dispatchHookSingle(scope, CREATE_PRINCIPAL_HOOK, method);
|
|
128
|
+
const principal = await getPrincipal(scope, method) ?? await createPrincipal(scope, method);
|
|
119
129
|
if (principal) {
|
|
120
|
-
const session = await
|
|
130
|
+
const session = await createSession(scope, principal);
|
|
121
131
|
if (session) {
|
|
122
132
|
await setSession(scope, session);
|
|
123
133
|
return sendRedirect(scope, flow.redirect);
|
|
@@ -155,17 +165,206 @@ function defineAuthProvider(provider) {
|
|
|
155
165
|
return sendRedirect(scope, withQuery(scope, options.authorize.url, parameters));
|
|
156
166
|
} };
|
|
157
167
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
168
|
+
async function useServerAuth(scope) {
|
|
169
|
+
return {
|
|
170
|
+
...await useAccountStorage(scope),
|
|
171
|
+
...await useOrganizationStorage(scope)
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
async function useAccountStorage(scope) {
|
|
175
|
+
return useStorageProvider(scope, await Promise.all([
|
|
176
|
+
import("./storage/sqlite.js"),
|
|
177
|
+
import("./storage/postgresql.js"),
|
|
178
|
+
import("./storage/mysql.js")
|
|
179
|
+
]), (provider) => provider.accountSchema).useAccountStorage(scope);
|
|
180
|
+
}
|
|
181
|
+
async function useOrganizationStorage(scope) {
|
|
182
|
+
if (!config.organizations) throw new Error("Organizations is disabled. Set auth.organizations to true to use Organizations storage.");
|
|
183
|
+
return useStorageProvider(scope, await Promise.all([
|
|
184
|
+
import("./storage/sqlite.js"),
|
|
185
|
+
import("./storage/postgresql.js"),
|
|
186
|
+
import("./storage/mysql.js")
|
|
187
|
+
]), (provider) => provider.accountSchema).useOrganizationStorage(scope);
|
|
188
|
+
}
|
|
189
|
+
async function getPrincipal(scope, method) {
|
|
190
|
+
if (method.type === "PASSWORD") {
|
|
191
|
+
if ((await dispatchHook(scope, BEFORE_PRINCIPAL_GET_HOOK, method)).includes(false)) return false;
|
|
192
|
+
if ((await dispatchHook(scope, BEFORE_ACCOUNT_GET_HOOK, "email", method.email)).includes(false)) return false;
|
|
193
|
+
const account = await (await useAccountStorage(scope)).getAccountByEmail(method.email);
|
|
194
|
+
if (!account) return;
|
|
195
|
+
await dispatchHook(scope, AFTER_ACCOUNT_GET_HOOK, account);
|
|
196
|
+
if (account.password !== method.password) return;
|
|
197
|
+
const principal = {
|
|
198
|
+
sub: account.id,
|
|
199
|
+
email: account.email
|
|
200
|
+
};
|
|
201
|
+
await dispatchHook(scope, AFTER_PRINCIPAL_GET_HOOK, principal, method);
|
|
202
|
+
return principal;
|
|
203
|
+
} else if (method.type === "PROVIDER") {
|
|
204
|
+
if ((await dispatchHook(scope, BEFORE_PRINCIPAL_GET_HOOK, method)).includes(false)) return false;
|
|
205
|
+
if ((await dispatchHook(scope, BEFORE_IDENTITY_GET_HOOK, method.issuer, method.principal.sub)).includes(false)) return false;
|
|
206
|
+
const storage = await useAccountStorage(scope);
|
|
207
|
+
const identity = await storage.getIdentity(method.issuer, method.principal.sub);
|
|
208
|
+
if (!identity) return;
|
|
209
|
+
await dispatchHook(scope, AFTER_IDENTITY_GET_HOOK, identity);
|
|
210
|
+
if ((await dispatchHook(scope, BEFORE_ACCOUNT_GET_HOOK, "id", identity.accountId)).includes(false)) return false;
|
|
211
|
+
const account = await storage.getAccountById(identity.accountId);
|
|
212
|
+
if (!account) return;
|
|
213
|
+
await dispatchHook(scope, AFTER_ACCOUNT_GET_HOOK, account);
|
|
214
|
+
const principal = {
|
|
215
|
+
sub: account.id,
|
|
216
|
+
email: account.email
|
|
217
|
+
};
|
|
218
|
+
await dispatchHook(scope, AFTER_PRINCIPAL_GET_HOOK, principal, method);
|
|
219
|
+
return principal;
|
|
220
|
+
} else if (method.type === "PASSKEY") throw new Error("Passkey authentication is not implemented.");
|
|
221
|
+
}
|
|
222
|
+
async function createPrincipal(scope, method) {
|
|
223
|
+
if (method.type === "PASSWORD") {
|
|
224
|
+
if (!method.register) return;
|
|
225
|
+
if ((await dispatchHook(scope, BEFORE_PRINCIPAL_CREATE_HOOK, method)).includes(false)) return;
|
|
226
|
+
const storage = await useAccountStorage(scope);
|
|
227
|
+
if ((await dispatchHook(scope, BEFORE_ACCOUNT_GET_HOOK, "email", method.email)).includes(false)) return;
|
|
228
|
+
const existing = await storage.getAccountByEmail(method.email);
|
|
229
|
+
if (existing) {
|
|
230
|
+
await dispatchHook(scope, AFTER_ACCOUNT_GET_HOOK, existing);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
const account = {
|
|
234
|
+
id: crypto.randomUUID(),
|
|
235
|
+
email: method.email,
|
|
236
|
+
password: method.password,
|
|
237
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
238
|
+
};
|
|
239
|
+
const beforeAccountCreate = await dispatchHook(scope, BEFORE_ACCOUNT_CREATE_HOOK, account, method);
|
|
240
|
+
if (beforeAccountCreate.includes(false)) return;
|
|
241
|
+
const accountFields = Object.keys(account);
|
|
242
|
+
for (const values of beforeAccountCreate) {
|
|
243
|
+
if (!values || typeof values !== "object") continue;
|
|
244
|
+
for (const key of Object.keys(values)) if (accountFields.includes(key)) throw new Error(`Auth account create values cannot replace field "${key}".`);
|
|
245
|
+
Object.assign(account, values);
|
|
246
|
+
}
|
|
247
|
+
const createdAccount = await storage.createAccount(account);
|
|
248
|
+
if (!createdAccount) throw new Error("Unable to read the created Auth account.");
|
|
249
|
+
await dispatchHook(scope, AFTER_ACCOUNT_CREATE_HOOK, createdAccount);
|
|
250
|
+
const principal = {
|
|
251
|
+
sub: createdAccount.id,
|
|
252
|
+
email: createdAccount.email
|
|
253
|
+
};
|
|
254
|
+
await dispatchHook(scope, AFTER_PRINCIPAL_CREATE_HOOK, principal, method);
|
|
255
|
+
return principal;
|
|
256
|
+
} else if (method.type === "PROVIDER") {
|
|
257
|
+
if ((await dispatchHook(scope, BEFORE_PRINCIPAL_CREATE_HOOK, method)).includes(false)) return;
|
|
258
|
+
const storage = await useAccountStorage(scope);
|
|
259
|
+
const account = {
|
|
260
|
+
id: crypto.randomUUID(),
|
|
261
|
+
email: method.principal.email ?? "",
|
|
262
|
+
password: null,
|
|
263
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
264
|
+
};
|
|
265
|
+
const beforeAccountCreate = await dispatchHook(scope, BEFORE_ACCOUNT_CREATE_HOOK, account, method);
|
|
266
|
+
if (beforeAccountCreate.includes(false)) return;
|
|
267
|
+
const accountFields = Object.keys(account);
|
|
268
|
+
for (const values of beforeAccountCreate) {
|
|
269
|
+
if (!values || typeof values !== "object") continue;
|
|
270
|
+
for (const key of Object.keys(values)) if (accountFields.includes(key)) throw new Error(`Auth account create values cannot replace field "${key}".`);
|
|
271
|
+
Object.assign(account, values);
|
|
272
|
+
}
|
|
273
|
+
const identity = {
|
|
274
|
+
id: crypto.randomUUID(),
|
|
275
|
+
provider: method.issuer,
|
|
276
|
+
credential: method.principal.sub,
|
|
277
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
278
|
+
accountId: account.id
|
|
279
|
+
};
|
|
280
|
+
const beforeIdentityCreate = await dispatchHook(scope, BEFORE_IDENTITY_CREATE_HOOK, identity, method);
|
|
281
|
+
if (beforeIdentityCreate.includes(false)) return;
|
|
282
|
+
const identityFields = Object.keys(identity);
|
|
283
|
+
for (const values of beforeIdentityCreate) {
|
|
284
|
+
if (!values || typeof values !== "object") continue;
|
|
285
|
+
for (const key of Object.keys(values)) if (identityFields.includes(key)) throw new Error(`Auth identity create values cannot replace field "${key}".`);
|
|
286
|
+
Object.assign(identity, values);
|
|
287
|
+
}
|
|
288
|
+
const createdAccount = await storage.createAccount(account);
|
|
289
|
+
if (!createdAccount) throw new Error("Unable to read the created Auth account.");
|
|
290
|
+
let createdIdentity;
|
|
291
|
+
try {
|
|
292
|
+
createdIdentity = await storage.createIdentity(identity);
|
|
293
|
+
if (!createdIdentity) throw new Error("Unable to read the created Auth identity.");
|
|
294
|
+
} catch (error) {
|
|
295
|
+
await storage.deleteAccount(createdAccount.id);
|
|
296
|
+
throw error;
|
|
297
|
+
}
|
|
298
|
+
await dispatchHook(scope, AFTER_ACCOUNT_CREATE_HOOK, createdAccount);
|
|
299
|
+
await dispatchHook(scope, AFTER_IDENTITY_CREATE_HOOK, createdIdentity);
|
|
300
|
+
const principal = {
|
|
301
|
+
sub: createdAccount.id,
|
|
302
|
+
email: createdAccount.email
|
|
303
|
+
};
|
|
304
|
+
await dispatchHook(scope, AFTER_PRINCIPAL_CREATE_HOOK, principal, method);
|
|
305
|
+
return principal;
|
|
306
|
+
} else if (method.type === "PASSKEY") throw new Error("Passkey authentication is not implemented.");
|
|
307
|
+
}
|
|
308
|
+
async function createSession(scope, principal) {
|
|
309
|
+
const storage = await useAccountStorage(scope);
|
|
310
|
+
const session = {
|
|
311
|
+
id: crypto.randomUUID(),
|
|
312
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
313
|
+
accountId: principal.sub
|
|
314
|
+
};
|
|
315
|
+
const beforeSessionCreate = await dispatchHook(scope, BEFORE_SESSION_CREATE_HOOK, session, principal);
|
|
316
|
+
if (beforeSessionCreate.includes(false)) return;
|
|
317
|
+
const sessionFields = Object.keys(session);
|
|
318
|
+
for (const values of beforeSessionCreate) {
|
|
319
|
+
if (!values || typeof values !== "object") continue;
|
|
320
|
+
for (const key of Object.keys(values)) if (sessionFields.includes(key)) throw new Error(`Auth session create values cannot replace field "${key}".`);
|
|
321
|
+
Object.assign(session, values);
|
|
322
|
+
}
|
|
323
|
+
const created = await storage.createSession(session);
|
|
324
|
+
if (!created) throw new Error("Unable to read the created Auth session.");
|
|
325
|
+
await dispatchHook(scope, AFTER_SESSION_CREATE_HOOK, created);
|
|
326
|
+
return created;
|
|
327
|
+
}
|
|
328
|
+
var authIdSchema = pipe(string(), minLength(1), maxLength(128));
|
|
329
|
+
var organizationNameSchema = pipe(string(), maxLength(200), trim(), minLength(1));
|
|
330
|
+
var organizationParametersSchema = object({ organizationId: authIdSchema });
|
|
331
|
+
var membershipParametersSchema = object({
|
|
332
|
+
organizationId: authIdSchema,
|
|
333
|
+
membershipId: authIdSchema
|
|
334
|
+
});
|
|
335
|
+
var BEFORE_PRINCIPAL_GET_HOOK = defineHook("BEFORE_PRINCIPAL_GET_HOOK");
|
|
336
|
+
var AFTER_PRINCIPAL_GET_HOOK = defineHook("AFTER_PRINCIPAL_GET_HOOK");
|
|
337
|
+
var BEFORE_PRINCIPAL_CREATE_HOOK = defineHook("BEFORE_PRINCIPAL_CREATE_HOOK");
|
|
338
|
+
var AFTER_PRINCIPAL_CREATE_HOOK = defineHook("AFTER_PRINCIPAL_CREATE_HOOK");
|
|
339
|
+
var BEFORE_ACCOUNT_GET_HOOK = defineHook("BEFORE_ACCOUNT_GET_HOOK");
|
|
340
|
+
var AFTER_ACCOUNT_GET_HOOK = defineHook("AFTER_ACCOUNT_GET_HOOK");
|
|
341
|
+
var BEFORE_IDENTITY_GET_HOOK = defineHook("BEFORE_IDENTITY_GET_HOOK");
|
|
342
|
+
var AFTER_IDENTITY_GET_HOOK = defineHook("AFTER_IDENTITY_GET_HOOK");
|
|
343
|
+
var BEFORE_SESSION_GET_HOOK = defineHook("BEFORE_SESSION_GET_HOOK");
|
|
344
|
+
var AFTER_SESSION_GET_HOOK = defineHook("AFTER_SESSION_GET_HOOK");
|
|
345
|
+
var BEFORE_ACCOUNT_CREATE_HOOK = defineHook("BEFORE_ACCOUNT_CREATE_HOOK");
|
|
346
|
+
var AFTER_ACCOUNT_CREATE_HOOK = defineHook("AFTER_ACCOUNT_CREATE_HOOK");
|
|
347
|
+
var BEFORE_IDENTITY_CREATE_HOOK = defineHook("BEFORE_IDENTITY_CREATE_HOOK");
|
|
348
|
+
var AFTER_IDENTITY_CREATE_HOOK = defineHook("AFTER_IDENTITY_CREATE_HOOK");
|
|
349
|
+
var BEFORE_SESSION_CREATE_HOOK = defineHook("BEFORE_SESSION_CREATE_HOOK");
|
|
350
|
+
var AFTER_SESSION_CREATE_HOOK = defineHook("AFTER_SESSION_CREATE_HOOK");
|
|
163
351
|
var registerAuthHooks = createRegisterHooks({
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
352
|
+
beforePrincipalGet: BEFORE_PRINCIPAL_GET_HOOK,
|
|
353
|
+
afterPrincipalGet: AFTER_PRINCIPAL_GET_HOOK,
|
|
354
|
+
beforePrincipalCreate: BEFORE_PRINCIPAL_CREATE_HOOK,
|
|
355
|
+
afterPrincipalCreate: AFTER_PRINCIPAL_CREATE_HOOK,
|
|
356
|
+
beforeAccountGet: BEFORE_ACCOUNT_GET_HOOK,
|
|
357
|
+
afterAccountGet: AFTER_ACCOUNT_GET_HOOK,
|
|
358
|
+
beforeIdentityGet: BEFORE_IDENTITY_GET_HOOK,
|
|
359
|
+
afterIdentityGet: AFTER_IDENTITY_GET_HOOK,
|
|
360
|
+
beforeSessionGet: BEFORE_SESSION_GET_HOOK,
|
|
361
|
+
afterSessionGet: AFTER_SESSION_GET_HOOK,
|
|
362
|
+
beforeAccountCreate: BEFORE_ACCOUNT_CREATE_HOOK,
|
|
363
|
+
afterAccountCreate: AFTER_ACCOUNT_CREATE_HOOK,
|
|
364
|
+
beforeIdentityCreate: BEFORE_IDENTITY_CREATE_HOOK,
|
|
365
|
+
afterIdentityCreate: AFTER_IDENTITY_CREATE_HOOK,
|
|
366
|
+
beforeSessionCreate: BEFORE_SESSION_CREATE_HOOK,
|
|
367
|
+
afterSessionCreate: AFTER_SESSION_CREATE_HOOK
|
|
169
368
|
});
|
|
170
369
|
var principalSchema = object({
|
|
171
370
|
sub: string(),
|
|
@@ -180,7 +379,7 @@ var passwordMethodSchema = object({
|
|
|
180
379
|
type: literal("PASSWORD"),
|
|
181
380
|
email: string(),
|
|
182
381
|
password: string(),
|
|
183
|
-
register: optional(boolean(),
|
|
382
|
+
register: optional(boolean(), false)
|
|
184
383
|
});
|
|
185
384
|
var passkeyMethodSchema = object({ type: literal("PASSKEY") });
|
|
186
385
|
var providerMethodSchema = object({
|
|
@@ -234,4 +433,4 @@ var BASE64_VERIFY = { alphabet: "base64url" };
|
|
|
234
433
|
var encoder = new TextEncoder();
|
|
235
434
|
var decoder = new TextDecoder();
|
|
236
435
|
//#endregion
|
|
237
|
-
export {
|
|
436
|
+
export { AFTER_ACCOUNT_CREATE_HOOK, AFTER_ACCOUNT_GET_HOOK, AFTER_IDENTITY_CREATE_HOOK, AFTER_IDENTITY_GET_HOOK, AFTER_PRINCIPAL_CREATE_HOOK, AFTER_PRINCIPAL_GET_HOOK, AFTER_SESSION_CREATE_HOOK, AFTER_SESSION_GET_HOOK, BEFORE_ACCOUNT_CREATE_HOOK, BEFORE_ACCOUNT_GET_HOOK, BEFORE_IDENTITY_CREATE_HOOK, BEFORE_IDENTITY_GET_HOOK, BEFORE_PRINCIPAL_CREATE_HOOK, BEFORE_PRINCIPAL_GET_HOOK, BEFORE_SESSION_CREATE_HOOK, BEFORE_SESSION_GET_HOOK, authIdSchema, clearSession, createPrincipal, createSession, defineAuthProvider, getCryptoKey, getPrincipal, getSession, membershipParametersSchema, methodSchema, organizationNameSchema, organizationParametersSchema, passkeyMethodSchema, passwordMethodSchema, principalSchema, providerMethodSchema, registerAuthHooks, requireSession, setSession, useAccountStorage, useClientAuth, useOrganizationStorage, useServerAuth };
|
package/dist/module/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export interface SessionOptions {
|
|
|
6
6
|
cookie: CookieOptions;
|
|
7
7
|
}
|
|
8
8
|
export interface AuthConfig {
|
|
9
|
+
organizations: boolean;
|
|
9
10
|
session: SessionOptions;
|
|
10
11
|
providers?: Partial<Record<Providers | (string & {}), Mergeable<Pick<AuthProviderOptions, "scope" | "pkce" | "authorize" | "token" | "userInfo">>>>;
|
|
11
12
|
}
|