@spfn/auth 0.1.0-alpha.1 → 0.1.0-alpha.86
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/README.md +250 -0
- package/dist/adapters/nextjs/api.d.ts +446 -0
- package/dist/adapters/nextjs/api.js +3279 -0
- package/dist/adapters/nextjs/api.js.map +1 -0
- package/dist/adapters/nextjs/server.d.ts +246 -0
- package/dist/adapters/nextjs/server.js +3645 -0
- package/dist/adapters/nextjs/server.js.map +1 -0
- package/dist/index.d.ts +3 -46
- package/dist/index.js +777 -645
- package/dist/index.js.map +1 -1
- package/dist/lib/api/auth-codes-verify.d.ts +37 -0
- package/dist/lib/api/auth-codes-verify.js +2949 -0
- package/dist/lib/api/auth-codes-verify.js.map +1 -0
- package/dist/lib/api/auth-codes.d.ts +37 -0
- package/dist/lib/api/auth-codes.js +2949 -0
- package/dist/lib/api/auth-codes.js.map +1 -0
- package/dist/lib/api/auth-exists.d.ts +38 -0
- package/dist/lib/api/auth-exists.js +2949 -0
- package/dist/lib/api/auth-exists.js.map +1 -0
- package/dist/lib/api/auth-invitations-accept.d.ts +38 -0
- package/dist/lib/api/auth-invitations-accept.js +2883 -0
- package/dist/lib/api/auth-invitations-accept.js.map +1 -0
- package/dist/lib/api/auth-invitations-cancel.d.ts +37 -0
- package/dist/lib/api/auth-invitations-cancel.js +2883 -0
- package/dist/lib/api/auth-invitations-cancel.js.map +1 -0
- package/dist/lib/api/auth-invitations-delete.d.ts +36 -0
- package/dist/lib/api/auth-invitations-delete.js +2883 -0
- package/dist/lib/api/auth-invitations-delete.js.map +1 -0
- package/dist/lib/api/auth-invitations-resend.d.ts +37 -0
- package/dist/lib/api/auth-invitations-resend.js +2883 -0
- package/dist/lib/api/auth-invitations-resend.js.map +1 -0
- package/dist/lib/api/auth-invitations.d.ts +109 -0
- package/dist/lib/api/auth-invitations.js +2887 -0
- package/dist/lib/api/auth-invitations.js.map +1 -0
- package/dist/lib/api/auth-keys-rotate.d.ts +37 -0
- package/dist/lib/api/auth-keys-rotate.js +2949 -0
- package/dist/lib/api/auth-keys-rotate.js.map +1 -0
- package/dist/lib/api/auth-login.d.ts +39 -0
- package/dist/lib/api/auth-login.js +2949 -0
- package/dist/lib/api/auth-login.js.map +1 -0
- package/dist/lib/api/auth-logout.d.ts +36 -0
- package/dist/lib/api/auth-logout.js +2949 -0
- package/dist/lib/api/auth-logout.js.map +1 -0
- package/dist/lib/api/auth-me.d.ts +50 -0
- package/dist/lib/api/auth-me.js +2949 -0
- package/dist/lib/api/auth-me.js.map +1 -0
- package/dist/lib/api/auth-password.d.ts +36 -0
- package/dist/lib/api/auth-password.js +2949 -0
- package/dist/lib/api/auth-password.js.map +1 -0
- package/dist/lib/api/auth-register.d.ts +38 -0
- package/dist/lib/api/auth-register.js +2949 -0
- package/dist/lib/api/auth-register.js.map +1 -0
- package/dist/lib/api/index.d.ts +356 -0
- package/dist/lib/api/index.js +3261 -0
- package/dist/lib/api/index.js.map +1 -0
- package/dist/lib/config.d.ts +70 -0
- package/dist/lib/config.js +64 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/contracts/auth.d.ts +41 -1
- package/dist/lib/contracts/auth.js +28 -0
- package/dist/lib/contracts/auth.js.map +1 -1
- package/dist/lib/contracts/index.d.ts +1 -1
- package/dist/lib/contracts/index.js +28 -0
- package/dist/lib/contracts/index.js.map +1 -1
- package/dist/lib/crypto.d.ts +76 -0
- package/dist/lib/crypto.js +127 -0
- package/dist/lib/crypto.js.map +1 -0
- package/dist/lib/index.d.ts +4 -0
- package/dist/lib/index.js +313 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/session.d.ts +68 -0
- package/dist/lib/session.js +126 -0
- package/dist/lib/session.js.map +1 -0
- package/dist/{api-BcQM4WKb.d.ts → lib/types/api.d.ts} +2 -2
- package/dist/lib/types/api.js +1 -0
- package/dist/lib/types/api.js.map +1 -0
- package/dist/lib/types/index.d.ts +3 -0
- package/dist/lib/types/index.js +2647 -0
- package/dist/lib/types/index.js.map +1 -0
- package/dist/lib/types/schemas.d.ts +45 -0
- package/dist/lib/types/schemas.js +2647 -0
- package/dist/lib/types/schemas.js.map +1 -0
- package/dist/lib.d.ts +2 -0
- package/dist/lib.js +1 -0
- package/dist/lib.js.map +1 -0
- package/dist/plugin.js +777 -645
- package/dist/plugin.js.map +1 -1
- package/dist/server/entities/index.d.ts +1 -0
- package/dist/server/entities/index.js +23 -27
- package/dist/server/entities/index.js.map +1 -1
- package/dist/server/entities/invitations.js +12 -9
- package/dist/server/entities/invitations.js.map +1 -1
- package/dist/server/entities/permissions.js +8 -3
- package/dist/server/entities/permissions.js.map +1 -1
- package/dist/server/entities/role-permissions.js +12 -9
- package/dist/server/entities/role-permissions.js.map +1 -1
- package/dist/server/entities/roles.js +8 -3
- package/dist/server/entities/roles.js.map +1 -1
- package/dist/server/entities/schema.d.ts +14 -0
- package/dist/server/entities/schema.js +7 -0
- package/dist/server/entities/schema.js.map +1 -0
- package/dist/server/entities/user-permissions.js +14 -12
- package/dist/server/entities/user-permissions.js.map +1 -1
- package/dist/server/entities/user-public-keys.js +12 -9
- package/dist/server/entities/user-public-keys.js.map +1 -1
- package/dist/server/entities/user-social-accounts.js +12 -9
- package/dist/server/entities/user-social-accounts.js.map +1 -1
- package/dist/server/entities/users.js +10 -6
- package/dist/server/entities/users.js.map +1 -1
- package/dist/server/entities/verification-codes.js +8 -3
- package/dist/server/entities/verification-codes.js.map +1 -1
- package/dist/server/routes/auth/index.js +495 -512
- package/dist/server/routes/auth/index.js.map +1 -1
- package/dist/server/routes/index.js +775 -545
- package/dist/server/routes/index.js.map +1 -1
- package/dist/server/routes/invitations/index.js +416 -230
- package/dist/server/routes/invitations/index.js.map +1 -1
- package/dist/server.d.ts +91 -62
- package/dist/server.js +320 -327
- package/dist/server.js.map +1 -1
- package/migrations/{0000_tired_gambit.sql → 0000_complex_swordsman.sql} +2 -0
- package/migrations/meta/0000_snapshot.json +4 -2
- package/migrations/meta/_journal.json +2 -2
- package/package.json +30 -3
package/dist/plugin.js
CHANGED
|
@@ -8,15 +8,25 @@ var __export = (target, all) => {
|
|
|
8
8
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
+
// src/server/entities/schema.ts
|
|
12
|
+
import { createFunctionSchema } from "@spfn/core/db";
|
|
13
|
+
var authSchema;
|
|
14
|
+
var init_schema = __esm({
|
|
15
|
+
"src/server/entities/schema.ts"() {
|
|
16
|
+
"use strict";
|
|
17
|
+
authSchema = createFunctionSchema("@spfn/auth");
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
|
|
11
21
|
// src/server/entities/roles.ts
|
|
12
22
|
import { text, boolean, integer, index } from "drizzle-orm/pg-core";
|
|
13
|
-
import { id, timestamps
|
|
14
|
-
var
|
|
23
|
+
import { id, timestamps } from "@spfn/core/db";
|
|
24
|
+
var roles;
|
|
15
25
|
var init_roles = __esm({
|
|
16
26
|
"src/server/entities/roles.ts"() {
|
|
17
27
|
"use strict";
|
|
18
|
-
|
|
19
|
-
roles =
|
|
28
|
+
init_schema();
|
|
29
|
+
roles = authSchema.table(
|
|
20
30
|
"roles",
|
|
21
31
|
{
|
|
22
32
|
// Primary key
|
|
@@ -58,15 +68,15 @@ var init_roles = __esm({
|
|
|
58
68
|
|
|
59
69
|
// src/server/entities/users.ts
|
|
60
70
|
import { text as text2, timestamp, check, boolean as boolean2, bigint, index as index2 } from "drizzle-orm/pg-core";
|
|
61
|
-
import { id as id2, timestamps as timestamps2
|
|
71
|
+
import { id as id2, timestamps as timestamps2 } from "@spfn/core/db";
|
|
62
72
|
import { sql } from "drizzle-orm";
|
|
63
|
-
var
|
|
73
|
+
var users;
|
|
64
74
|
var init_users = __esm({
|
|
65
75
|
"src/server/entities/users.ts"() {
|
|
66
76
|
"use strict";
|
|
67
77
|
init_roles();
|
|
68
|
-
|
|
69
|
-
users =
|
|
78
|
+
init_schema();
|
|
79
|
+
users = authSchema.table(
|
|
70
80
|
"users",
|
|
71
81
|
{
|
|
72
82
|
// Identity
|
|
@@ -131,14 +141,14 @@ var init_users = __esm({
|
|
|
131
141
|
|
|
132
142
|
// src/server/entities/user-social-accounts.ts
|
|
133
143
|
import { text as text3, timestamp as timestamp2, uniqueIndex } from "drizzle-orm/pg-core";
|
|
134
|
-
import { id as id3, timestamps as timestamps3, foreignKey
|
|
135
|
-
var
|
|
144
|
+
import { id as id3, timestamps as timestamps3, foreignKey } from "@spfn/core/db";
|
|
145
|
+
var userSocialAccounts;
|
|
136
146
|
var init_user_social_accounts = __esm({
|
|
137
147
|
"src/server/entities/user-social-accounts.ts"() {
|
|
138
148
|
"use strict";
|
|
139
149
|
init_users();
|
|
140
|
-
|
|
141
|
-
userSocialAccounts =
|
|
150
|
+
init_schema();
|
|
151
|
+
userSocialAccounts = authSchema.table(
|
|
142
152
|
"user_social_accounts",
|
|
143
153
|
{
|
|
144
154
|
id: id3(),
|
|
@@ -169,14 +179,14 @@ var init_user_social_accounts = __esm({
|
|
|
169
179
|
|
|
170
180
|
// src/server/entities/user-public-keys.ts
|
|
171
181
|
import { text as text4, timestamp as timestamp3, boolean as boolean3, index as index3 } from "drizzle-orm/pg-core";
|
|
172
|
-
import { id as id4, foreignKey as foreignKey2
|
|
173
|
-
var
|
|
182
|
+
import { id as id4, foreignKey as foreignKey2 } from "@spfn/core/db";
|
|
183
|
+
var userPublicKeys;
|
|
174
184
|
var init_user_public_keys = __esm({
|
|
175
185
|
"src/server/entities/user-public-keys.ts"() {
|
|
176
186
|
"use strict";
|
|
177
187
|
init_users();
|
|
178
|
-
|
|
179
|
-
userPublicKeys =
|
|
188
|
+
init_schema();
|
|
189
|
+
userPublicKeys = authSchema.table(
|
|
180
190
|
"user_public_keys",
|
|
181
191
|
{
|
|
182
192
|
id: id4(),
|
|
@@ -214,13 +224,13 @@ var init_user_public_keys = __esm({
|
|
|
214
224
|
|
|
215
225
|
// src/server/entities/verification-codes.ts
|
|
216
226
|
import { text as text5, timestamp as timestamp4, index as index4 } from "drizzle-orm/pg-core";
|
|
217
|
-
import { id as id5, timestamps as timestamps4
|
|
218
|
-
var
|
|
227
|
+
import { id as id5, timestamps as timestamps4 } from "@spfn/core/db";
|
|
228
|
+
var verificationCodes;
|
|
219
229
|
var init_verification_codes = __esm({
|
|
220
230
|
"src/server/entities/verification-codes.ts"() {
|
|
221
231
|
"use strict";
|
|
222
|
-
|
|
223
|
-
verificationCodes =
|
|
232
|
+
init_schema();
|
|
233
|
+
verificationCodes = authSchema.table(
|
|
224
234
|
"verification_codes",
|
|
225
235
|
{
|
|
226
236
|
id: id5(),
|
|
@@ -261,15 +271,15 @@ var init_verification_codes = __esm({
|
|
|
261
271
|
|
|
262
272
|
// src/server/entities/invitations.ts
|
|
263
273
|
import { text as text6, timestamp as timestamp5, bigint as bigint2, index as index5, jsonb } from "drizzle-orm/pg-core";
|
|
264
|
-
import { id as id6, timestamps as timestamps5
|
|
265
|
-
var
|
|
274
|
+
import { id as id6, timestamps as timestamps5 } from "@spfn/core/db";
|
|
275
|
+
var invitations;
|
|
266
276
|
var init_invitations = __esm({
|
|
267
277
|
"src/server/entities/invitations.ts"() {
|
|
268
278
|
"use strict";
|
|
269
279
|
init_roles();
|
|
270
280
|
init_users();
|
|
271
|
-
|
|
272
|
-
invitations =
|
|
281
|
+
init_schema();
|
|
282
|
+
invitations = authSchema.table(
|
|
273
283
|
"user_invitations",
|
|
274
284
|
{
|
|
275
285
|
// Primary key
|
|
@@ -337,13 +347,13 @@ var init_invitations = __esm({
|
|
|
337
347
|
|
|
338
348
|
// src/server/entities/permissions.ts
|
|
339
349
|
import { text as text7, boolean as boolean4, index as index6 } from "drizzle-orm/pg-core";
|
|
340
|
-
import { id as id7, timestamps as timestamps6
|
|
341
|
-
var
|
|
350
|
+
import { id as id7, timestamps as timestamps6 } from "@spfn/core/db";
|
|
351
|
+
var permissions;
|
|
342
352
|
var init_permissions = __esm({
|
|
343
353
|
"src/server/entities/permissions.ts"() {
|
|
344
354
|
"use strict";
|
|
345
|
-
|
|
346
|
-
permissions =
|
|
355
|
+
init_schema();
|
|
356
|
+
permissions = authSchema.table(
|
|
347
357
|
"permissions",
|
|
348
358
|
{
|
|
349
359
|
// Primary key
|
|
@@ -384,15 +394,15 @@ var init_permissions = __esm({
|
|
|
384
394
|
|
|
385
395
|
// src/server/entities/role-permissions.ts
|
|
386
396
|
import { bigint as bigint3, index as index7, unique } from "drizzle-orm/pg-core";
|
|
387
|
-
import { id as id8, timestamps as timestamps7
|
|
388
|
-
var
|
|
397
|
+
import { id as id8, timestamps as timestamps7 } from "@spfn/core/db";
|
|
398
|
+
var rolePermissions;
|
|
389
399
|
var init_role_permissions = __esm({
|
|
390
400
|
"src/server/entities/role-permissions.ts"() {
|
|
391
401
|
"use strict";
|
|
392
402
|
init_roles();
|
|
393
403
|
init_permissions();
|
|
394
|
-
|
|
395
|
-
rolePermissions =
|
|
404
|
+
init_schema();
|
|
405
|
+
rolePermissions = authSchema.table(
|
|
396
406
|
"role_permissions",
|
|
397
407
|
{
|
|
398
408
|
// Primary key
|
|
@@ -416,15 +426,15 @@ var init_role_permissions = __esm({
|
|
|
416
426
|
|
|
417
427
|
// src/server/entities/user-permissions.ts
|
|
418
428
|
import { bigint as bigint4, boolean as boolean5, text as text8, timestamp as timestamp6, index as index8, unique as unique2 } from "drizzle-orm/pg-core";
|
|
419
|
-
import { id as id9, timestamps as timestamps8
|
|
420
|
-
var
|
|
429
|
+
import { id as id9, timestamps as timestamps8 } from "@spfn/core/db";
|
|
430
|
+
var userPermissions;
|
|
421
431
|
var init_user_permissions = __esm({
|
|
422
432
|
"src/server/entities/user-permissions.ts"() {
|
|
423
433
|
"use strict";
|
|
424
434
|
init_users();
|
|
425
435
|
init_permissions();
|
|
426
|
-
|
|
427
|
-
userPermissions =
|
|
436
|
+
init_schema();
|
|
437
|
+
userPermissions = authSchema.table(
|
|
428
438
|
"user_permissions",
|
|
429
439
|
{
|
|
430
440
|
// Primary key
|
|
@@ -460,6 +470,7 @@ var init_user_permissions = __esm({
|
|
|
460
470
|
// src/server/entities/index.ts
|
|
461
471
|
var entities_exports = {};
|
|
462
472
|
__export(entities_exports, {
|
|
473
|
+
authSchema: () => authSchema,
|
|
463
474
|
invitations: () => invitations,
|
|
464
475
|
permissions: () => permissions,
|
|
465
476
|
rolePermissions: () => rolePermissions,
|
|
@@ -473,6 +484,7 @@ __export(entities_exports, {
|
|
|
473
484
|
var init_entities = __esm({
|
|
474
485
|
"src/server/entities/index.ts"() {
|
|
475
486
|
"use strict";
|
|
487
|
+
init_schema();
|
|
476
488
|
init_users();
|
|
477
489
|
init_user_social_accounts();
|
|
478
490
|
init_user_public_keys();
|
|
@@ -558,6 +570,14 @@ var init_builtin = __esm({
|
|
|
558
570
|
isSystem: true,
|
|
559
571
|
isBuiltin: true
|
|
560
572
|
},
|
|
573
|
+
USER_INVITE: {
|
|
574
|
+
name: "user:invite",
|
|
575
|
+
displayName: "Invite Users",
|
|
576
|
+
description: "Create and send user invitations",
|
|
577
|
+
category: "user",
|
|
578
|
+
isSystem: true,
|
|
579
|
+
isBuiltin: true
|
|
580
|
+
},
|
|
561
581
|
// RBAC management (superadmin functions)
|
|
562
582
|
RBAC_ROLE_MANAGE: {
|
|
563
583
|
name: "rbac:role:manage",
|
|
@@ -582,6 +602,7 @@ var init_builtin = __esm({
|
|
|
582
602
|
"user:read",
|
|
583
603
|
"user:write",
|
|
584
604
|
"user:delete",
|
|
605
|
+
"user:invite",
|
|
585
606
|
"rbac:role:manage",
|
|
586
607
|
"rbac:permission:manage"
|
|
587
608
|
],
|
|
@@ -589,7 +610,8 @@ var init_builtin = __esm({
|
|
|
589
610
|
"auth:self:manage",
|
|
590
611
|
"user:read",
|
|
591
612
|
"user:write",
|
|
592
|
-
"user:delete"
|
|
613
|
+
"user:delete",
|
|
614
|
+
"user:invite"
|
|
593
615
|
],
|
|
594
616
|
user: [
|
|
595
617
|
"auth:self:manage"
|
|
@@ -598,167 +620,64 @@ var init_builtin = __esm({
|
|
|
598
620
|
}
|
|
599
621
|
});
|
|
600
622
|
|
|
601
|
-
// src/server/rbac/presets.ts
|
|
602
|
-
var PRESET_ROLES, PRESET_PERMISSIONS, PRESET_ROLE_PERMISSIONS;
|
|
603
|
-
var init_presets = __esm({
|
|
604
|
-
"src/server/rbac/presets.ts"() {
|
|
605
|
-
"use strict";
|
|
606
|
-
PRESET_ROLES = {
|
|
607
|
-
MODERATOR: {
|
|
608
|
-
name: "moderator",
|
|
609
|
-
displayName: "Moderator",
|
|
610
|
-
description: "Content moderation and community management",
|
|
611
|
-
priority: 50,
|
|
612
|
-
isSystem: true
|
|
613
|
-
},
|
|
614
|
-
EDITOR: {
|
|
615
|
-
name: "editor",
|
|
616
|
-
displayName: "Editor",
|
|
617
|
-
description: "Content creation and editing",
|
|
618
|
-
priority: 30,
|
|
619
|
-
isSystem: true
|
|
620
|
-
},
|
|
621
|
-
VIEWER: {
|
|
622
|
-
name: "viewer",
|
|
623
|
-
displayName: "Viewer",
|
|
624
|
-
description: "Read-only access to content",
|
|
625
|
-
priority: 5,
|
|
626
|
-
isSystem: true
|
|
627
|
-
}
|
|
628
|
-
};
|
|
629
|
-
PRESET_PERMISSIONS = {
|
|
630
|
-
// Content management
|
|
631
|
-
CONTENT_READ: {
|
|
632
|
-
name: "content:read",
|
|
633
|
-
displayName: "Read Content",
|
|
634
|
-
description: "View all content including drafts",
|
|
635
|
-
category: "content",
|
|
636
|
-
isSystem: true
|
|
637
|
-
},
|
|
638
|
-
CONTENT_WRITE: {
|
|
639
|
-
name: "content:write",
|
|
640
|
-
displayName: "Write Content",
|
|
641
|
-
description: "Create and edit content",
|
|
642
|
-
category: "content",
|
|
643
|
-
isSystem: true
|
|
644
|
-
},
|
|
645
|
-
CONTENT_DELETE: {
|
|
646
|
-
name: "content:delete",
|
|
647
|
-
displayName: "Delete Content",
|
|
648
|
-
description: "Delete any content",
|
|
649
|
-
category: "content",
|
|
650
|
-
isSystem: true
|
|
651
|
-
},
|
|
652
|
-
CONTENT_PUBLISH: {
|
|
653
|
-
name: "content:publish",
|
|
654
|
-
displayName: "Publish Content",
|
|
655
|
-
description: "Publish content to make it public",
|
|
656
|
-
category: "content",
|
|
657
|
-
isSystem: true
|
|
658
|
-
},
|
|
659
|
-
// Moderation
|
|
660
|
-
COMMENT_MODERATE: {
|
|
661
|
-
name: "comment:moderate",
|
|
662
|
-
displayName: "Moderate Comments",
|
|
663
|
-
description: "Review and delete inappropriate comments",
|
|
664
|
-
category: "moderation",
|
|
665
|
-
isSystem: true
|
|
666
|
-
},
|
|
667
|
-
// System
|
|
668
|
-
SYSTEM_CONFIG: {
|
|
669
|
-
name: "system:config",
|
|
670
|
-
displayName: "System Configuration",
|
|
671
|
-
description: "Configure application settings",
|
|
672
|
-
category: "system",
|
|
673
|
-
isSystem: true
|
|
674
|
-
},
|
|
675
|
-
// Analytics
|
|
676
|
-
ANALYTICS_VIEW: {
|
|
677
|
-
name: "analytics:view",
|
|
678
|
-
displayName: "View Analytics",
|
|
679
|
-
description: "Access analytics dashboard and reports",
|
|
680
|
-
category: "analytics",
|
|
681
|
-
isSystem: true
|
|
682
|
-
}
|
|
683
|
-
};
|
|
684
|
-
PRESET_ROLE_PERMISSIONS = {
|
|
685
|
-
moderator: [
|
|
686
|
-
"auth:self:manage",
|
|
687
|
-
"user:read",
|
|
688
|
-
"content:read",
|
|
689
|
-
"content:write",
|
|
690
|
-
"content:delete",
|
|
691
|
-
"comment:moderate"
|
|
692
|
-
],
|
|
693
|
-
editor: [
|
|
694
|
-
"auth:self:manage",
|
|
695
|
-
"content:read",
|
|
696
|
-
"content:write",
|
|
697
|
-
"content:publish"
|
|
698
|
-
],
|
|
699
|
-
viewer: [
|
|
700
|
-
"auth:self:manage",
|
|
701
|
-
"content:read"
|
|
702
|
-
]
|
|
703
|
-
};
|
|
704
|
-
}
|
|
705
|
-
});
|
|
706
|
-
|
|
707
623
|
// src/server/rbac/index.ts
|
|
708
624
|
var init_rbac = __esm({
|
|
709
625
|
"src/server/rbac/index.ts"() {
|
|
710
626
|
"use strict";
|
|
711
627
|
init_types();
|
|
712
628
|
init_builtin();
|
|
713
|
-
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
// src/lib/config.ts
|
|
633
|
+
function configureAuth(config) {
|
|
634
|
+
globalConfig = {
|
|
635
|
+
...globalConfig,
|
|
636
|
+
...config
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
var globalConfig;
|
|
640
|
+
var init_config = __esm({
|
|
641
|
+
"src/lib/config.ts"() {
|
|
642
|
+
"use strict";
|
|
643
|
+
globalConfig = {
|
|
644
|
+
sessionTtl: "7d"
|
|
645
|
+
// Default: 7 days
|
|
646
|
+
};
|
|
714
647
|
}
|
|
715
648
|
});
|
|
716
649
|
|
|
717
650
|
// src/server/services/rbac.service.ts
|
|
718
651
|
import { getDatabase } from "@spfn/core/db";
|
|
652
|
+
import { logger } from "@spfn/core/logger";
|
|
719
653
|
import { eq, and, inArray } from "drizzle-orm";
|
|
720
654
|
async function initializeAuth(options = {}) {
|
|
721
655
|
const db = getDatabase();
|
|
722
656
|
if (!db) {
|
|
723
657
|
throw new Error("[Auth] Database not initialized. Call initDatabase() first.");
|
|
724
658
|
}
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
if (PRESET_ROLES[presetKey]) {
|
|
732
|
-
allRoles.push(PRESET_ROLES[presetKey]);
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
if (options.roles) {
|
|
737
|
-
allRoles.push(...options.roles);
|
|
659
|
+
authLogger.info("\u{1F510} Initializing RBAC system...");
|
|
660
|
+
if (options.sessionTtl !== void 0) {
|
|
661
|
+
configureAuth({
|
|
662
|
+
sessionTtl: options.sessionTtl
|
|
663
|
+
});
|
|
664
|
+
authLogger.info(`\u23F1\uFE0F Session TTL: ${options.sessionTtl}`);
|
|
738
665
|
}
|
|
666
|
+
const allRoles = [
|
|
667
|
+
...Object.values(BUILTIN_ROLES),
|
|
668
|
+
...options.roles || []
|
|
669
|
+
];
|
|
739
670
|
for (const roleConfig of allRoles) {
|
|
740
671
|
await upsertRole(roleConfig);
|
|
741
672
|
}
|
|
742
|
-
const allPermissions = [
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
for (const presetKey of options.presetPermissions) {
|
|
747
|
-
if (PRESET_PERMISSIONS[presetKey]) {
|
|
748
|
-
allPermissions.push(PRESET_PERMISSIONS[presetKey]);
|
|
749
|
-
}
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
if (options.permissions) {
|
|
753
|
-
allPermissions.push(...options.permissions);
|
|
754
|
-
}
|
|
673
|
+
const allPermissions = [
|
|
674
|
+
...Object.values(BUILTIN_PERMISSIONS),
|
|
675
|
+
...options.permissions || []
|
|
676
|
+
];
|
|
755
677
|
for (const permConfig of allPermissions) {
|
|
756
678
|
await upsertPermission(permConfig);
|
|
757
679
|
}
|
|
758
680
|
const allMappings = { ...BUILTIN_ROLE_PERMISSIONS };
|
|
759
|
-
if (options.usePresets) {
|
|
760
|
-
Object.assign(allMappings, PRESET_ROLE_PERMISSIONS);
|
|
761
|
-
}
|
|
762
681
|
if (options.rolePermissions) {
|
|
763
682
|
for (const [roleName, permNames] of Object.entries(options.rolePermissions)) {
|
|
764
683
|
if (allMappings[roleName]) {
|
|
@@ -773,9 +692,9 @@ async function initializeAuth(options = {}) {
|
|
|
773
692
|
for (const [roleName, permNames] of Object.entries(allMappings)) {
|
|
774
693
|
await assignPermissionsToRole(roleName, permNames);
|
|
775
694
|
}
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
695
|
+
authLogger.info("\u2705 RBAC initialization complete");
|
|
696
|
+
authLogger.info(`\u{1F4CA} Roles: ${allRoles.length}, Permissions: ${allPermissions.length}`);
|
|
697
|
+
authLogger.info("\u{1F512} Built-in roles: user, admin, superadmin");
|
|
779
698
|
}
|
|
780
699
|
async function upsertRole(config) {
|
|
781
700
|
const db = getDatabase();
|
|
@@ -789,7 +708,7 @@ async function upsertRole(config) {
|
|
|
789
708
|
isSystem: config.isSystem ?? false,
|
|
790
709
|
isBuiltin: config.isBuiltin ?? false
|
|
791
710
|
});
|
|
792
|
-
|
|
711
|
+
authLogger.info(` \u2705 Created role: ${config.name}`);
|
|
793
712
|
} else {
|
|
794
713
|
const updateData = {
|
|
795
714
|
displayName: config.displayName,
|
|
@@ -813,7 +732,7 @@ async function upsertPermission(config) {
|
|
|
813
732
|
isSystem: config.isSystem ?? false,
|
|
814
733
|
isBuiltin: config.isBuiltin ?? false
|
|
815
734
|
});
|
|
816
|
-
|
|
735
|
+
authLogger.info(` \u2705 Created permission: ${config.name}`);
|
|
817
736
|
} else {
|
|
818
737
|
await db.update(permissions).set({
|
|
819
738
|
displayName: config.displayName,
|
|
@@ -826,12 +745,12 @@ async function assignPermissionsToRole(roleName, permissionNames) {
|
|
|
826
745
|
const db = getDatabase();
|
|
827
746
|
const [role] = await db.select().from(roles).where(eq(roles.name, roleName)).limit(1);
|
|
828
747
|
if (!role) {
|
|
829
|
-
|
|
748
|
+
authLogger.warn(` \u26A0\uFE0F Role not found: ${roleName}, skipping permission assignment`);
|
|
830
749
|
return;
|
|
831
750
|
}
|
|
832
751
|
const perms = await db.select().from(permissions).where(inArray(permissions.name, permissionNames));
|
|
833
752
|
if (perms.length === 0) {
|
|
834
|
-
|
|
753
|
+
authLogger.warn(` \u26A0\uFE0F No permissions found for role: ${roleName}`);
|
|
835
754
|
return;
|
|
836
755
|
}
|
|
837
756
|
for (const perm of perms) {
|
|
@@ -849,11 +768,14 @@ async function assignPermissionsToRole(roleName, permissionNames) {
|
|
|
849
768
|
}
|
|
850
769
|
}
|
|
851
770
|
}
|
|
771
|
+
var authLogger;
|
|
852
772
|
var init_rbac_service = __esm({
|
|
853
773
|
"src/server/services/rbac.service.ts"() {
|
|
854
774
|
"use strict";
|
|
855
775
|
init_entities();
|
|
856
776
|
init_rbac();
|
|
777
|
+
init_config();
|
|
778
|
+
authLogger = logger.child("@spfn/auth");
|
|
857
779
|
}
|
|
858
780
|
});
|
|
859
781
|
|
|
@@ -2619,8 +2541,8 @@ var init_value2 = __esm({
|
|
|
2619
2541
|
});
|
|
2620
2542
|
|
|
2621
2543
|
// ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/clone/type.mjs
|
|
2622
|
-
function CloneType(
|
|
2623
|
-
return options === void 0 ? Clone(
|
|
2544
|
+
function CloneType(schema, options) {
|
|
2545
|
+
return options === void 0 ? Clone(schema) : Clone({ ...options, ...schema });
|
|
2624
2546
|
}
|
|
2625
2547
|
var init_type = __esm({
|
|
2626
2548
|
"../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/clone/type.mjs"() {
|
|
@@ -2737,8 +2659,8 @@ var init_immutable = __esm({
|
|
|
2737
2659
|
});
|
|
2738
2660
|
|
|
2739
2661
|
// ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/create/type.mjs
|
|
2740
|
-
function CreateType(
|
|
2741
|
-
const result = options !== void 0 ? { ...options, ...
|
|
2662
|
+
function CreateType(schema, options) {
|
|
2663
|
+
const result = options !== void 0 ? { ...options, ...schema } : schema;
|
|
2742
2664
|
switch (TypeSystemPolicy.InstanceMode) {
|
|
2743
2665
|
case "freeze":
|
|
2744
2666
|
return Immutable(result);
|
|
@@ -3068,16 +2990,16 @@ function IsBoolean3(value) {
|
|
|
3068
2990
|
return IsKindOf2(value, "Boolean") && value.type === "boolean" && IsOptionalString(value.$id);
|
|
3069
2991
|
}
|
|
3070
2992
|
function IsComputed2(value) {
|
|
3071
|
-
return IsKindOf2(value, "Computed") && IsString(value.target) && IsArray(value.parameters) && value.parameters.every((
|
|
2993
|
+
return IsKindOf2(value, "Computed") && IsString(value.target) && IsArray(value.parameters) && value.parameters.every((schema) => IsSchema2(schema));
|
|
3072
2994
|
}
|
|
3073
2995
|
function IsConstructor2(value) {
|
|
3074
|
-
return IsKindOf2(value, "Constructor") && value.type === "Constructor" && IsOptionalString(value.$id) && IsArray(value.parameters) && value.parameters.every((
|
|
2996
|
+
return IsKindOf2(value, "Constructor") && value.type === "Constructor" && IsOptionalString(value.$id) && IsArray(value.parameters) && value.parameters.every((schema) => IsSchema2(schema)) && IsSchema2(value.returns);
|
|
3075
2997
|
}
|
|
3076
2998
|
function IsDate3(value) {
|
|
3077
2999
|
return IsKindOf2(value, "Date") && value.type === "Date" && IsOptionalString(value.$id) && IsOptionalNumber(value.exclusiveMaximumTimestamp) && IsOptionalNumber(value.exclusiveMinimumTimestamp) && IsOptionalNumber(value.maximumTimestamp) && IsOptionalNumber(value.minimumTimestamp) && IsOptionalNumber(value.multipleOfTimestamp);
|
|
3078
3000
|
}
|
|
3079
3001
|
function IsFunction3(value) {
|
|
3080
|
-
return IsKindOf2(value, "Function") && value.type === "Function" && IsOptionalString(value.$id) && IsArray(value.parameters) && value.parameters.every((
|
|
3002
|
+
return IsKindOf2(value, "Function") && value.type === "Function" && IsOptionalString(value.$id) && IsArray(value.parameters) && value.parameters.every((schema) => IsSchema2(schema)) && IsSchema2(value.returns);
|
|
3081
3003
|
}
|
|
3082
3004
|
function IsImport(value) {
|
|
3083
3005
|
return IsKindOf2(value, "Import") && HasPropertyKey(value, "$defs") && IsObject(value.$defs) && IsProperties(value.$defs) && HasPropertyKey(value, "$ref") && IsString(value.$ref) && value.$ref in value.$defs;
|
|
@@ -3086,10 +3008,10 @@ function IsInteger2(value) {
|
|
|
3086
3008
|
return IsKindOf2(value, "Integer") && value.type === "integer" && IsOptionalString(value.$id) && IsOptionalNumber(value.exclusiveMaximum) && IsOptionalNumber(value.exclusiveMinimum) && IsOptionalNumber(value.maximum) && IsOptionalNumber(value.minimum) && IsOptionalNumber(value.multipleOf);
|
|
3087
3009
|
}
|
|
3088
3010
|
function IsProperties(value) {
|
|
3089
|
-
return IsObject(value) && Object.entries(value).every(([key,
|
|
3011
|
+
return IsObject(value) && Object.entries(value).every(([key, schema]) => IsControlCharacterFree(key) && IsSchema2(schema));
|
|
3090
3012
|
}
|
|
3091
3013
|
function IsIntersect2(value) {
|
|
3092
|
-
return IsKindOf2(value, "Intersect") && (IsString(value.type) && value.type !== "object" ? false : true) && IsArray(value.allOf) && value.allOf.every((
|
|
3014
|
+
return IsKindOf2(value, "Intersect") && (IsString(value.type) && value.type !== "object" ? false : true) && IsArray(value.allOf) && value.allOf.every((schema) => IsSchema2(schema) && !IsTransform2(schema)) && IsOptionalString(value.type) && (IsOptionalBoolean(value.unevaluatedProperties) || IsOptionalSchema(value.unevaluatedProperties)) && IsOptionalString(value.$id);
|
|
3093
3015
|
}
|
|
3094
3016
|
function IsIterator3(value) {
|
|
3095
3017
|
return IsKindOf2(value, "Iterator") && value.type === "Iterator" && IsOptionalString(value.$id) && IsSchema2(value.items);
|
|
@@ -3137,9 +3059,9 @@ function IsPromise2(value) {
|
|
|
3137
3059
|
return IsKindOf2(value, "Promise") && value.type === "Promise" && IsOptionalString(value.$id) && IsSchema2(value.item);
|
|
3138
3060
|
}
|
|
3139
3061
|
function IsRecord2(value) {
|
|
3140
|
-
return IsKindOf2(value, "Record") && value.type === "object" && IsOptionalString(value.$id) && IsAdditionalProperties(value.additionalProperties) && IsObject(value.patternProperties) && ((
|
|
3141
|
-
const keys = Object.getOwnPropertyNames(
|
|
3142
|
-
return keys.length === 1 && IsPattern(keys[0]) && IsObject(
|
|
3062
|
+
return IsKindOf2(value, "Record") && value.type === "object" && IsOptionalString(value.$id) && IsAdditionalProperties(value.additionalProperties) && IsObject(value.patternProperties) && ((schema) => {
|
|
3063
|
+
const keys = Object.getOwnPropertyNames(schema.patternProperties);
|
|
3064
|
+
return keys.length === 1 && IsPattern(keys[0]) && IsObject(schema.patternProperties) && IsSchema2(schema.patternProperties[keys[0]]);
|
|
3143
3065
|
})(value);
|
|
3144
3066
|
}
|
|
3145
3067
|
function IsRecursive(value) {
|
|
@@ -3168,16 +3090,16 @@ function IsTransform2(value) {
|
|
|
3168
3090
|
}
|
|
3169
3091
|
function IsTuple2(value) {
|
|
3170
3092
|
return IsKindOf2(value, "Tuple") && value.type === "array" && IsOptionalString(value.$id) && IsNumber(value.minItems) && IsNumber(value.maxItems) && value.minItems === value.maxItems && // empty
|
|
3171
|
-
(IsUndefined(value.items) && IsUndefined(value.additionalItems) && value.minItems === 0 || IsArray(value.items) && value.items.every((
|
|
3093
|
+
(IsUndefined(value.items) && IsUndefined(value.additionalItems) && value.minItems === 0 || IsArray(value.items) && value.items.every((schema) => IsSchema2(schema)));
|
|
3172
3094
|
}
|
|
3173
3095
|
function IsUndefined4(value) {
|
|
3174
3096
|
return IsKindOf2(value, "Undefined") && value.type === "undefined" && IsOptionalString(value.$id);
|
|
3175
3097
|
}
|
|
3176
3098
|
function IsUnionLiteral(value) {
|
|
3177
|
-
return IsUnion2(value) && value.anyOf.every((
|
|
3099
|
+
return IsUnion2(value) && value.anyOf.every((schema) => IsLiteralString(schema) || IsLiteralNumber(schema));
|
|
3178
3100
|
}
|
|
3179
3101
|
function IsUnion2(value) {
|
|
3180
|
-
return IsKindOf2(value, "Union") && IsOptionalString(value.$id) && IsObject(value) && IsArray(value.anyOf) && value.anyOf.every((
|
|
3102
|
+
return IsKindOf2(value, "Union") && IsOptionalString(value.$id) && IsObject(value) && IsArray(value.anyOf) && value.anyOf.every((schema) => IsSchema2(schema));
|
|
3181
3103
|
}
|
|
3182
3104
|
function IsUint8Array3(value) {
|
|
3183
3105
|
return IsKindOf2(value, "Uint8Array") && value.type === "Uint8Array" && IsOptionalString(value.$id) && IsOptionalNumber(value.minByteLength) && IsOptionalNumber(value.maxByteLength);
|
|
@@ -3778,8 +3700,8 @@ function IsTemplateLiteralExpressionFinite(expression) {
|
|
|
3778
3700
|
throw new TemplateLiteralFiniteError(`Unknown expression type`);
|
|
3779
3701
|
})();
|
|
3780
3702
|
}
|
|
3781
|
-
function IsTemplateLiteralFinite(
|
|
3782
|
-
const expression = TemplateLiteralParseExact(
|
|
3703
|
+
function IsTemplateLiteralFinite(schema) {
|
|
3704
|
+
const expression = TemplateLiteralParseExact(schema.pattern);
|
|
3783
3705
|
return IsTemplateLiteralExpressionFinite(expression);
|
|
3784
3706
|
}
|
|
3785
3707
|
var TemplateLiteralFiniteError;
|
|
@@ -3818,8 +3740,8 @@ function* TemplateLiteralExpressionGenerate(expression) {
|
|
|
3818
3740
|
throw new TemplateLiteralGenerateError("Unknown expression");
|
|
3819
3741
|
})();
|
|
3820
3742
|
}
|
|
3821
|
-
function TemplateLiteralGenerate(
|
|
3822
|
-
const expression = TemplateLiteralParseExact(
|
|
3743
|
+
function TemplateLiteralGenerate(schema) {
|
|
3744
|
+
const expression = TemplateLiteralParseExact(schema.pattern);
|
|
3823
3745
|
return IsTemplateLiteralExpressionFinite(expression) ? [...TemplateLiteralExpressionGenerate(expression)] : [];
|
|
3824
3746
|
}
|
|
3825
3747
|
var TemplateLiteralGenerateError;
|
|
@@ -3991,13 +3913,13 @@ var init_syntax = __esm({
|
|
|
3991
3913
|
function Escape(value) {
|
|
3992
3914
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3993
3915
|
}
|
|
3994
|
-
function Visit2(
|
|
3995
|
-
return IsTemplateLiteral(
|
|
3996
|
-
throw new TemplateLiteralPatternError(`Unexpected Kind '${
|
|
3916
|
+
function Visit2(schema, acc) {
|
|
3917
|
+
return IsTemplateLiteral(schema) ? schema.pattern.slice(1, schema.pattern.length - 1) : IsUnion(schema) ? `(${schema.anyOf.map((schema2) => Visit2(schema2, acc)).join("|")})` : IsNumber3(schema) ? `${acc}${PatternNumber}` : IsInteger(schema) ? `${acc}${PatternNumber}` : IsBigInt2(schema) ? `${acc}${PatternNumber}` : IsString2(schema) ? `${acc}${PatternString}` : IsLiteral(schema) ? `${acc}${Escape(schema.const.toString())}` : IsBoolean2(schema) ? `${acc}${PatternBoolean}` : (() => {
|
|
3918
|
+
throw new TemplateLiteralPatternError(`Unexpected Kind '${schema[Kind]}'`);
|
|
3997
3919
|
})();
|
|
3998
3920
|
}
|
|
3999
3921
|
function TemplateLiteralPattern(kinds) {
|
|
4000
|
-
return `^${kinds.map((
|
|
3922
|
+
return `^${kinds.map((schema) => Visit2(schema, "")).join("")}$`;
|
|
4001
3923
|
}
|
|
4002
3924
|
var TemplateLiteralPatternError;
|
|
4003
3925
|
var init_pattern = __esm({
|
|
@@ -4013,8 +3935,8 @@ var init_pattern = __esm({
|
|
|
4013
3935
|
});
|
|
4014
3936
|
|
|
4015
3937
|
// ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/template-literal/union.mjs
|
|
4016
|
-
function TemplateLiteralToUnion(
|
|
4017
|
-
const R = TemplateLiteralGenerate(
|
|
3938
|
+
function TemplateLiteralToUnion(schema) {
|
|
3939
|
+
const R = TemplateLiteralGenerate(schema);
|
|
4018
3940
|
const L = R.map((S) => Literal(S));
|
|
4019
3941
|
return UnionEvaluated(L);
|
|
4020
3942
|
}
|
|
@@ -4279,18 +4201,18 @@ var init_promise2 = __esm({
|
|
|
4279
4201
|
});
|
|
4280
4202
|
|
|
4281
4203
|
// ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/readonly/readonly.mjs
|
|
4282
|
-
function RemoveReadonly(
|
|
4283
|
-
return CreateType(Discard(
|
|
4204
|
+
function RemoveReadonly(schema) {
|
|
4205
|
+
return CreateType(Discard(schema, [ReadonlyKind]));
|
|
4284
4206
|
}
|
|
4285
|
-
function AddReadonly(
|
|
4286
|
-
return CreateType({ ...
|
|
4207
|
+
function AddReadonly(schema) {
|
|
4208
|
+
return CreateType({ ...schema, [ReadonlyKind]: "Readonly" });
|
|
4287
4209
|
}
|
|
4288
|
-
function ReadonlyWithFlag(
|
|
4289
|
-
return F === false ? RemoveReadonly(
|
|
4210
|
+
function ReadonlyWithFlag(schema, F) {
|
|
4211
|
+
return F === false ? RemoveReadonly(schema) : AddReadonly(schema);
|
|
4290
4212
|
}
|
|
4291
|
-
function Readonly(
|
|
4213
|
+
function Readonly(schema, enable) {
|
|
4292
4214
|
const F = enable ?? true;
|
|
4293
|
-
return IsMappedResult(
|
|
4215
|
+
return IsMappedResult(schema) ? ReadonlyFromMappedResult(schema, F) : ReadonlyWithFlag(schema, F);
|
|
4294
4216
|
}
|
|
4295
4217
|
var init_readonly = __esm({
|
|
4296
4218
|
"../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/readonly/readonly.mjs"() {
|
|
@@ -4444,18 +4366,18 @@ var init_mapped2 = __esm({
|
|
|
4444
4366
|
});
|
|
4445
4367
|
|
|
4446
4368
|
// ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/optional/optional.mjs
|
|
4447
|
-
function RemoveOptional(
|
|
4448
|
-
return CreateType(Discard(
|
|
4369
|
+
function RemoveOptional(schema) {
|
|
4370
|
+
return CreateType(Discard(schema, [OptionalKind]));
|
|
4449
4371
|
}
|
|
4450
|
-
function AddOptional(
|
|
4451
|
-
return CreateType({ ...
|
|
4372
|
+
function AddOptional(schema) {
|
|
4373
|
+
return CreateType({ ...schema, [OptionalKind]: "Optional" });
|
|
4452
4374
|
}
|
|
4453
|
-
function OptionalWithFlag(
|
|
4454
|
-
return F === false ? RemoveOptional(
|
|
4375
|
+
function OptionalWithFlag(schema, F) {
|
|
4376
|
+
return F === false ? RemoveOptional(schema) : AddOptional(schema);
|
|
4455
4377
|
}
|
|
4456
|
-
function Optional(
|
|
4378
|
+
function Optional(schema, enable) {
|
|
4457
4379
|
const F = enable ?? true;
|
|
4458
|
-
return IsMappedResult(
|
|
4380
|
+
return IsMappedResult(schema) ? OptionalFromMappedResult(schema, F) : OptionalWithFlag(schema, F);
|
|
4459
4381
|
}
|
|
4460
4382
|
var init_optional = __esm({
|
|
4461
4383
|
"../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/optional/optional.mjs"() {
|
|
@@ -4501,7 +4423,7 @@ var init_optional2 = __esm({
|
|
|
4501
4423
|
|
|
4502
4424
|
// ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/intersect/intersect-create.mjs
|
|
4503
4425
|
function IntersectCreate(T, options = {}) {
|
|
4504
|
-
const allObjects = T.every((
|
|
4426
|
+
const allObjects = T.every((schema) => IsObject3(schema));
|
|
4505
4427
|
const clonedUnevaluatedProperties = IsSchema(options.unevaluatedProperties) ? { unevaluatedProperties: options.unevaluatedProperties } : {};
|
|
4506
4428
|
return CreateType(options.unevaluatedProperties === false || IsSchema(options.unevaluatedProperties) || allObjects ? { ...clonedUnevaluatedProperties, [Kind]: "Intersect", type: "object", allOf: T } : { ...clonedUnevaluatedProperties, [Kind]: "Intersect", allOf: T }, options);
|
|
4507
4429
|
}
|
|
@@ -4532,7 +4454,7 @@ function IntersectEvaluated(types, options = {}) {
|
|
|
4532
4454
|
return CreateType(types[0], options);
|
|
4533
4455
|
if (types.length === 0)
|
|
4534
4456
|
return Never(options);
|
|
4535
|
-
if (types.some((
|
|
4457
|
+
if (types.some((schema) => IsTransform(schema)))
|
|
4536
4458
|
throw new Error("Cannot intersect transform types");
|
|
4537
4459
|
return ResolveIntersect(types, options);
|
|
4538
4460
|
}
|
|
@@ -4562,7 +4484,7 @@ function Intersect(types, options) {
|
|
|
4562
4484
|
return CreateType(types[0], options);
|
|
4563
4485
|
if (types.length === 0)
|
|
4564
4486
|
return Never(options);
|
|
4565
|
-
if (types.some((
|
|
4487
|
+
if (types.some((schema) => IsTransform(schema)))
|
|
4566
4488
|
throw new Error("Cannot intersect transform types");
|
|
4567
4489
|
return IntersectCreate(types, options);
|
|
4568
4490
|
}
|
|
@@ -4992,8 +4914,8 @@ var init_const2 = __esm({
|
|
|
4992
4914
|
});
|
|
4993
4915
|
|
|
4994
4916
|
// ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/constructor-parameters/constructor-parameters.mjs
|
|
4995
|
-
function ConstructorParameters(
|
|
4996
|
-
return IsConstructor(
|
|
4917
|
+
function ConstructorParameters(schema, options) {
|
|
4918
|
+
return IsConstructor(schema) ? Tuple(schema.parameters, options) : Never(options);
|
|
4997
4919
|
}
|
|
4998
4920
|
var init_constructor_parameters = __esm({
|
|
4999
4921
|
"../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/constructor-parameters/constructor-parameters.mjs"() {
|
|
@@ -5056,7 +4978,7 @@ function FromAnyRight(left, right) {
|
|
|
5056
4978
|
return ExtendsResult.True;
|
|
5057
4979
|
}
|
|
5058
4980
|
function FromAny(left, right) {
|
|
5059
|
-
return type_exports.IsIntersect(right) ? FromIntersectRight(left, right) : type_exports.IsUnion(right) && right.anyOf.some((
|
|
4981
|
+
return type_exports.IsIntersect(right) ? FromIntersectRight(left, right) : type_exports.IsUnion(right) && right.anyOf.some((schema) => type_exports.IsAny(schema) || type_exports.IsUnknown(schema)) ? ExtendsResult.True : type_exports.IsUnion(right) ? ExtendsResult.Union : type_exports.IsUnknown(right) ? ExtendsResult.True : type_exports.IsAny(right) ? ExtendsResult.True : ExtendsResult.Union;
|
|
5060
4982
|
}
|
|
5061
4983
|
function FromArrayRight(left, right) {
|
|
5062
4984
|
return type_exports.IsUnknown(left) ? ExtendsResult.False : type_exports.IsAny(left) ? ExtendsResult.Union : type_exports.IsNever(left) ? ExtendsResult.True : ExtendsResult.False;
|
|
@@ -5077,13 +4999,13 @@ function FromBoolean(left, right) {
|
|
|
5077
4999
|
return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : type_exports.IsRecord(right) ? FromRecordRight(left, right) : type_exports.IsBoolean(right) ? ExtendsResult.True : ExtendsResult.False;
|
|
5078
5000
|
}
|
|
5079
5001
|
function FromConstructor(left, right) {
|
|
5080
|
-
return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : !type_exports.IsConstructor(right) ? ExtendsResult.False : left.parameters.length > right.parameters.length ? ExtendsResult.False : !left.parameters.every((
|
|
5002
|
+
return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : !type_exports.IsConstructor(right) ? ExtendsResult.False : left.parameters.length > right.parameters.length ? ExtendsResult.False : !left.parameters.every((schema, index9) => IntoBooleanResult(Visit3(right.parameters[index9], schema)) === ExtendsResult.True) ? ExtendsResult.False : IntoBooleanResult(Visit3(left.returns, right.returns));
|
|
5081
5003
|
}
|
|
5082
5004
|
function FromDate(left, right) {
|
|
5083
5005
|
return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : type_exports.IsRecord(right) ? FromRecordRight(left, right) : type_exports.IsDate(right) ? ExtendsResult.True : ExtendsResult.False;
|
|
5084
5006
|
}
|
|
5085
5007
|
function FromFunction(left, right) {
|
|
5086
|
-
return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : !type_exports.IsFunction(right) ? ExtendsResult.False : left.parameters.length > right.parameters.length ? ExtendsResult.False : !left.parameters.every((
|
|
5008
|
+
return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : !type_exports.IsFunction(right) ? ExtendsResult.False : left.parameters.length > right.parameters.length ? ExtendsResult.False : !left.parameters.every((schema, index9) => IntoBooleanResult(Visit3(right.parameters[index9], schema)) === ExtendsResult.True) ? ExtendsResult.False : IntoBooleanResult(Visit3(left.returns, right.returns));
|
|
5087
5009
|
}
|
|
5088
5010
|
function FromIntegerRight(left, right) {
|
|
5089
5011
|
return type_exports.IsLiteral(left) && value_exports.IsNumber(left.const) ? ExtendsResult.True : type_exports.IsNumber(left) || type_exports.IsInteger(left) ? ExtendsResult.True : ExtendsResult.False;
|
|
@@ -5092,10 +5014,10 @@ function FromInteger(left, right) {
|
|
|
5092
5014
|
return type_exports.IsInteger(right) || type_exports.IsNumber(right) ? ExtendsResult.True : IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : type_exports.IsRecord(right) ? FromRecordRight(left, right) : ExtendsResult.False;
|
|
5093
5015
|
}
|
|
5094
5016
|
function FromIntersectRight(left, right) {
|
|
5095
|
-
return right.allOf.every((
|
|
5017
|
+
return right.allOf.every((schema) => Visit3(left, schema) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
|
|
5096
5018
|
}
|
|
5097
5019
|
function FromIntersect4(left, right) {
|
|
5098
|
-
return left.allOf.some((
|
|
5020
|
+
return left.allOf.some((schema) => Visit3(schema, right) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
|
|
5099
5021
|
}
|
|
5100
5022
|
function FromIterator(left, right) {
|
|
5101
5023
|
return IsStructuralRight(right) ? StructuralRight(left, right) : !type_exports.IsIterator(right) ? ExtendsResult.False : IntoBooleanResult(Visit3(left.items, right.items));
|
|
@@ -5109,8 +5031,8 @@ function FromNeverRight(left, right) {
|
|
|
5109
5031
|
function FromNever(left, right) {
|
|
5110
5032
|
return ExtendsResult.True;
|
|
5111
5033
|
}
|
|
5112
|
-
function UnwrapTNot(
|
|
5113
|
-
let [current, depth] = [
|
|
5034
|
+
function UnwrapTNot(schema) {
|
|
5035
|
+
let [current, depth] = [schema, 0];
|
|
5114
5036
|
while (true) {
|
|
5115
5037
|
if (!type_exports.IsNot(current))
|
|
5116
5038
|
break;
|
|
@@ -5131,44 +5053,44 @@ function FromNumberRight(left, right) {
|
|
|
5131
5053
|
function FromNumber(left, right) {
|
|
5132
5054
|
return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : type_exports.IsRecord(right) ? FromRecordRight(left, right) : type_exports.IsInteger(right) || type_exports.IsNumber(right) ? ExtendsResult.True : ExtendsResult.False;
|
|
5133
5055
|
}
|
|
5134
|
-
function IsObjectPropertyCount(
|
|
5135
|
-
return Object.getOwnPropertyNames(
|
|
5056
|
+
function IsObjectPropertyCount(schema, count) {
|
|
5057
|
+
return Object.getOwnPropertyNames(schema.properties).length === count;
|
|
5136
5058
|
}
|
|
5137
|
-
function IsObjectStringLike(
|
|
5138
|
-
return IsObjectArrayLike(
|
|
5059
|
+
function IsObjectStringLike(schema) {
|
|
5060
|
+
return IsObjectArrayLike(schema);
|
|
5139
5061
|
}
|
|
5140
|
-
function IsObjectSymbolLike(
|
|
5141
|
-
return IsObjectPropertyCount(
|
|
5062
|
+
function IsObjectSymbolLike(schema) {
|
|
5063
|
+
return IsObjectPropertyCount(schema, 0) || IsObjectPropertyCount(schema, 1) && "description" in schema.properties && type_exports.IsUnion(schema.properties.description) && schema.properties.description.anyOf.length === 2 && (type_exports.IsString(schema.properties.description.anyOf[0]) && type_exports.IsUndefined(schema.properties.description.anyOf[1]) || type_exports.IsString(schema.properties.description.anyOf[1]) && type_exports.IsUndefined(schema.properties.description.anyOf[0]));
|
|
5142
5064
|
}
|
|
5143
|
-
function IsObjectNumberLike(
|
|
5144
|
-
return IsObjectPropertyCount(
|
|
5065
|
+
function IsObjectNumberLike(schema) {
|
|
5066
|
+
return IsObjectPropertyCount(schema, 0);
|
|
5145
5067
|
}
|
|
5146
|
-
function IsObjectBooleanLike(
|
|
5147
|
-
return IsObjectPropertyCount(
|
|
5068
|
+
function IsObjectBooleanLike(schema) {
|
|
5069
|
+
return IsObjectPropertyCount(schema, 0);
|
|
5148
5070
|
}
|
|
5149
|
-
function IsObjectBigIntLike(
|
|
5150
|
-
return IsObjectPropertyCount(
|
|
5071
|
+
function IsObjectBigIntLike(schema) {
|
|
5072
|
+
return IsObjectPropertyCount(schema, 0);
|
|
5151
5073
|
}
|
|
5152
|
-
function IsObjectDateLike(
|
|
5153
|
-
return IsObjectPropertyCount(
|
|
5074
|
+
function IsObjectDateLike(schema) {
|
|
5075
|
+
return IsObjectPropertyCount(schema, 0);
|
|
5154
5076
|
}
|
|
5155
|
-
function IsObjectUint8ArrayLike(
|
|
5156
|
-
return IsObjectArrayLike(
|
|
5077
|
+
function IsObjectUint8ArrayLike(schema) {
|
|
5078
|
+
return IsObjectArrayLike(schema);
|
|
5157
5079
|
}
|
|
5158
|
-
function IsObjectFunctionLike(
|
|
5080
|
+
function IsObjectFunctionLike(schema) {
|
|
5159
5081
|
const length = Number2();
|
|
5160
|
-
return IsObjectPropertyCount(
|
|
5082
|
+
return IsObjectPropertyCount(schema, 0) || IsObjectPropertyCount(schema, 1) && "length" in schema.properties && IntoBooleanResult(Visit3(schema.properties["length"], length)) === ExtendsResult.True;
|
|
5161
5083
|
}
|
|
5162
|
-
function IsObjectConstructorLike(
|
|
5163
|
-
return IsObjectPropertyCount(
|
|
5084
|
+
function IsObjectConstructorLike(schema) {
|
|
5085
|
+
return IsObjectPropertyCount(schema, 0);
|
|
5164
5086
|
}
|
|
5165
|
-
function IsObjectArrayLike(
|
|
5087
|
+
function IsObjectArrayLike(schema) {
|
|
5166
5088
|
const length = Number2();
|
|
5167
|
-
return IsObjectPropertyCount(
|
|
5089
|
+
return IsObjectPropertyCount(schema, 0) || IsObjectPropertyCount(schema, 1) && "length" in schema.properties && IntoBooleanResult(Visit3(schema.properties["length"], length)) === ExtendsResult.True;
|
|
5168
5090
|
}
|
|
5169
|
-
function IsObjectPromiseLike(
|
|
5091
|
+
function IsObjectPromiseLike(schema) {
|
|
5170
5092
|
const then = Function([Any()], Any());
|
|
5171
|
-
return IsObjectPropertyCount(
|
|
5093
|
+
return IsObjectPropertyCount(schema, 0) || IsObjectPropertyCount(schema, 1) && "then" in schema.properties && IntoBooleanResult(Visit3(schema.properties["then"], then)) === ExtendsResult.True;
|
|
5172
5094
|
}
|
|
5173
5095
|
function Property(left, right) {
|
|
5174
5096
|
return Visit3(left, right) === ExtendsResult.False ? ExtendsResult.False : type_exports.IsOptional(left) && !type_exports.IsOptional(right) ? ExtendsResult.False : ExtendsResult.True;
|
|
@@ -5199,11 +5121,11 @@ function FromObject(left, right) {
|
|
|
5199
5121
|
function FromPromise2(left, right) {
|
|
5200
5122
|
return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) && IsObjectPromiseLike(right) ? ExtendsResult.True : !type_exports.IsPromise(right) ? ExtendsResult.False : IntoBooleanResult(Visit3(left.item, right.item));
|
|
5201
5123
|
}
|
|
5202
|
-
function RecordKey(
|
|
5203
|
-
return PatternNumberExact in
|
|
5124
|
+
function RecordKey(schema) {
|
|
5125
|
+
return PatternNumberExact in schema.patternProperties ? Number2() : PatternStringExact in schema.patternProperties ? String2() : Throw("Unknown record key pattern");
|
|
5204
5126
|
}
|
|
5205
|
-
function RecordValue(
|
|
5206
|
-
return PatternNumberExact in
|
|
5127
|
+
function RecordValue(schema) {
|
|
5128
|
+
return PatternNumberExact in schema.patternProperties ? schema.patternProperties[PatternNumberExact] : PatternStringExact in schema.patternProperties ? schema.patternProperties[PatternStringExact] : Throw("Unable to get record value schema");
|
|
5207
5129
|
}
|
|
5208
5130
|
function FromRecordRight(left, right) {
|
|
5209
5131
|
const [Key, Value] = [RecordKey(right), RecordValue(right)];
|
|
@@ -5237,13 +5159,13 @@ function FromTemplateLiteral2(left, right) {
|
|
|
5237
5159
|
return type_exports.IsTemplateLiteral(left) ? Visit3(TemplateLiteralToUnion(left), right) : type_exports.IsTemplateLiteral(right) ? Visit3(left, TemplateLiteralToUnion(right)) : Throw("Invalid fallthrough for TemplateLiteral");
|
|
5238
5160
|
}
|
|
5239
5161
|
function IsArrayOfTuple(left, right) {
|
|
5240
|
-
return type_exports.IsArray(right) && left.items !== void 0 && left.items.every((
|
|
5162
|
+
return type_exports.IsArray(right) && left.items !== void 0 && left.items.every((schema) => Visit3(schema, right.items) === ExtendsResult.True);
|
|
5241
5163
|
}
|
|
5242
5164
|
function FromTupleRight(left, right) {
|
|
5243
5165
|
return type_exports.IsNever(left) ? ExtendsResult.True : type_exports.IsUnknown(left) ? ExtendsResult.False : type_exports.IsAny(left) ? ExtendsResult.Union : ExtendsResult.False;
|
|
5244
5166
|
}
|
|
5245
5167
|
function FromTuple3(left, right) {
|
|
5246
|
-
return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) && IsObjectArrayLike(right) ? ExtendsResult.True : type_exports.IsArray(right) && IsArrayOfTuple(left, right) ? ExtendsResult.True : !type_exports.IsTuple(right) ? ExtendsResult.False : value_exports.IsUndefined(left.items) && !value_exports.IsUndefined(right.items) || !value_exports.IsUndefined(left.items) && value_exports.IsUndefined(right.items) ? ExtendsResult.False : value_exports.IsUndefined(left.items) && !value_exports.IsUndefined(right.items) ? ExtendsResult.True : left.items.every((
|
|
5168
|
+
return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) && IsObjectArrayLike(right) ? ExtendsResult.True : type_exports.IsArray(right) && IsArrayOfTuple(left, right) ? ExtendsResult.True : !type_exports.IsTuple(right) ? ExtendsResult.False : value_exports.IsUndefined(left.items) && !value_exports.IsUndefined(right.items) || !value_exports.IsUndefined(left.items) && value_exports.IsUndefined(right.items) ? ExtendsResult.False : value_exports.IsUndefined(left.items) && !value_exports.IsUndefined(right.items) ? ExtendsResult.True : left.items.every((schema, index9) => Visit3(schema, right.items[index9]) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
|
|
5247
5169
|
}
|
|
5248
5170
|
function FromUint8Array(left, right) {
|
|
5249
5171
|
return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : type_exports.IsRecord(right) ? FromRecordRight(left, right) : type_exports.IsUint8Array(right) ? ExtendsResult.True : ExtendsResult.False;
|
|
@@ -5252,10 +5174,10 @@ function FromUndefined(left, right) {
|
|
|
5252
5174
|
return IsStructuralRight(right) ? StructuralRight(left, right) : type_exports.IsObject(right) ? FromObjectRight(left, right) : type_exports.IsRecord(right) ? FromRecordRight(left, right) : type_exports.IsVoid(right) ? FromVoidRight(left, right) : type_exports.IsUndefined(right) ? ExtendsResult.True : ExtendsResult.False;
|
|
5253
5175
|
}
|
|
5254
5176
|
function FromUnionRight(left, right) {
|
|
5255
|
-
return right.anyOf.some((
|
|
5177
|
+
return right.anyOf.some((schema) => Visit3(left, schema) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
|
|
5256
5178
|
}
|
|
5257
5179
|
function FromUnion6(left, right) {
|
|
5258
|
-
return left.anyOf.every((
|
|
5180
|
+
return left.anyOf.every((schema) => Visit3(schema, right) === ExtendsResult.True) ? ExtendsResult.True : ExtendsResult.False;
|
|
5259
5181
|
}
|
|
5260
5182
|
function FromUnknownRight(left, right) {
|
|
5261
5183
|
return ExtendsResult.True;
|
|
@@ -5534,8 +5456,8 @@ var init_extract2 = __esm({
|
|
|
5534
5456
|
});
|
|
5535
5457
|
|
|
5536
5458
|
// ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/instance-type/instance-type.mjs
|
|
5537
|
-
function InstanceType(
|
|
5538
|
-
return IsConstructor(
|
|
5459
|
+
function InstanceType(schema, options) {
|
|
5460
|
+
return IsConstructor(schema) ? CreateType(schema.returns, options) : Never(options);
|
|
5539
5461
|
}
|
|
5540
5462
|
var init_instance_type = __esm({
|
|
5541
5463
|
"../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/instance-type/instance-type.mjs"() {
|
|
@@ -5555,8 +5477,8 @@ var init_instance_type2 = __esm({
|
|
|
5555
5477
|
});
|
|
5556
5478
|
|
|
5557
5479
|
// ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/readonly-optional/readonly-optional.mjs
|
|
5558
|
-
function ReadonlyOptional(
|
|
5559
|
-
return Readonly(Optional(
|
|
5480
|
+
function ReadonlyOptional(schema) {
|
|
5481
|
+
return Readonly(Optional(schema));
|
|
5560
5482
|
}
|
|
5561
5483
|
var init_readonly_optional = __esm({
|
|
5562
5484
|
"../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/readonly-optional/readonly-optional.mjs"() {
|
|
@@ -5815,11 +5737,11 @@ function ApplyUppercase(value) {
|
|
|
5815
5737
|
function ApplyLowercase(value) {
|
|
5816
5738
|
return value.toLowerCase();
|
|
5817
5739
|
}
|
|
5818
|
-
function FromTemplateLiteral3(
|
|
5819
|
-
const expression = TemplateLiteralParseExact(
|
|
5740
|
+
function FromTemplateLiteral3(schema, mode, options) {
|
|
5741
|
+
const expression = TemplateLiteralParseExact(schema.pattern);
|
|
5820
5742
|
const finite = IsTemplateLiteralExpressionFinite(expression);
|
|
5821
5743
|
if (!finite)
|
|
5822
|
-
return { ...
|
|
5744
|
+
return { ...schema, pattern: FromLiteralValue(schema.pattern, mode) };
|
|
5823
5745
|
const strings = [...TemplateLiteralExpressionGenerate(expression)];
|
|
5824
5746
|
const literals = strings.map((value) => Literal(value));
|
|
5825
5747
|
const mapped = FromRest5(literals, mode);
|
|
@@ -5832,14 +5754,14 @@ function FromLiteralValue(value, mode) {
|
|
|
5832
5754
|
function FromRest5(T, M) {
|
|
5833
5755
|
return T.map((L) => Intrinsic(L, M));
|
|
5834
5756
|
}
|
|
5835
|
-
function Intrinsic(
|
|
5757
|
+
function Intrinsic(schema, mode, options = {}) {
|
|
5836
5758
|
return (
|
|
5837
5759
|
// Intrinsic-Mapped-Inference
|
|
5838
|
-
IsMappedKey(
|
|
5760
|
+
IsMappedKey(schema) ? IntrinsicFromMappedKey(schema, mode, options) : (
|
|
5839
5761
|
// Standard-Inference
|
|
5840
|
-
IsTemplateLiteral(
|
|
5762
|
+
IsTemplateLiteral(schema) ? FromTemplateLiteral3(schema, mode, options) : IsUnion(schema) ? Union(FromRest5(schema.anyOf, mode), options) : IsLiteral(schema) ? Literal(FromLiteralValue(schema.const, mode), options) : (
|
|
5841
5763
|
// Default Type
|
|
5842
|
-
CreateType(
|
|
5764
|
+
CreateType(schema, options)
|
|
5843
5765
|
)
|
|
5844
5766
|
)
|
|
5845
5767
|
);
|
|
@@ -6496,8 +6418,8 @@ var init_not2 = __esm({
|
|
|
6496
6418
|
});
|
|
6497
6419
|
|
|
6498
6420
|
// ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/parameters/parameters.mjs
|
|
6499
|
-
function Parameters(
|
|
6500
|
-
return IsFunction2(
|
|
6421
|
+
function Parameters(schema, options) {
|
|
6422
|
+
return IsFunction2(schema) ? Tuple(schema.parameters, options) : Never();
|
|
6501
6423
|
}
|
|
6502
6424
|
var init_parameters = __esm({
|
|
6503
6425
|
"../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/parameters/parameters.mjs"() {
|
|
@@ -6589,8 +6511,8 @@ var init_rest2 = __esm({
|
|
|
6589
6511
|
});
|
|
6590
6512
|
|
|
6591
6513
|
// ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/return-type/return-type.mjs
|
|
6592
|
-
function ReturnType(
|
|
6593
|
-
return IsFunction2(
|
|
6514
|
+
function ReturnType(schema, options) {
|
|
6515
|
+
return IsFunction2(schema) ? CreateType(schema.returns, options) : Never(options);
|
|
6594
6516
|
}
|
|
6595
6517
|
var init_return_type = __esm({
|
|
6596
6518
|
"../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/return-type/return-type.mjs"() {
|
|
@@ -6617,18 +6539,18 @@ var init_anyschema = __esm({
|
|
|
6617
6539
|
});
|
|
6618
6540
|
|
|
6619
6541
|
// ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/schema/schema.mjs
|
|
6620
|
-
var
|
|
6542
|
+
var init_schema2 = __esm({
|
|
6621
6543
|
"../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/schema/schema.mjs"() {
|
|
6622
6544
|
"use strict";
|
|
6623
6545
|
}
|
|
6624
6546
|
});
|
|
6625
6547
|
|
|
6626
6548
|
// ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/schema/index.mjs
|
|
6627
|
-
var
|
|
6549
|
+
var init_schema3 = __esm({
|
|
6628
6550
|
"../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/schema/index.mjs"() {
|
|
6629
6551
|
"use strict";
|
|
6630
6552
|
init_anyschema();
|
|
6631
|
-
|
|
6553
|
+
init_schema2();
|
|
6632
6554
|
}
|
|
6633
6555
|
});
|
|
6634
6556
|
|
|
@@ -6648,8 +6570,8 @@ var init_static2 = __esm({
|
|
|
6648
6570
|
});
|
|
6649
6571
|
|
|
6650
6572
|
// ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/transform/transform.mjs
|
|
6651
|
-
function Transform(
|
|
6652
|
-
return new TransformDecodeBuilder(
|
|
6573
|
+
function Transform(schema) {
|
|
6574
|
+
return new TransformDecodeBuilder(schema);
|
|
6653
6575
|
}
|
|
6654
6576
|
var TransformDecodeBuilder, TransformEncodeBuilder;
|
|
6655
6577
|
var init_transform = __esm({
|
|
@@ -6658,27 +6580,27 @@ var init_transform = __esm({
|
|
|
6658
6580
|
init_symbols2();
|
|
6659
6581
|
init_kind();
|
|
6660
6582
|
TransformDecodeBuilder = class {
|
|
6661
|
-
constructor(
|
|
6662
|
-
this.schema =
|
|
6583
|
+
constructor(schema) {
|
|
6584
|
+
this.schema = schema;
|
|
6663
6585
|
}
|
|
6664
6586
|
Decode(decode) {
|
|
6665
6587
|
return new TransformEncodeBuilder(this.schema, decode);
|
|
6666
6588
|
}
|
|
6667
6589
|
};
|
|
6668
6590
|
TransformEncodeBuilder = class {
|
|
6669
|
-
constructor(
|
|
6670
|
-
this.schema =
|
|
6591
|
+
constructor(schema, decode) {
|
|
6592
|
+
this.schema = schema;
|
|
6671
6593
|
this.decode = decode;
|
|
6672
6594
|
}
|
|
6673
|
-
EncodeTransform(encode,
|
|
6674
|
-
const Encode = (value) =>
|
|
6675
|
-
const Decode = (value) => this.decode(
|
|
6595
|
+
EncodeTransform(encode, schema) {
|
|
6596
|
+
const Encode = (value) => schema[TransformKind].Encode(encode(value));
|
|
6597
|
+
const Decode = (value) => this.decode(schema[TransformKind].Decode(value));
|
|
6676
6598
|
const Codec = { Encode, Decode };
|
|
6677
|
-
return { ...
|
|
6599
|
+
return { ...schema, [TransformKind]: Codec };
|
|
6678
6600
|
}
|
|
6679
|
-
EncodeSchema(encode,
|
|
6601
|
+
EncodeSchema(encode, schema) {
|
|
6680
6602
|
const Codec = { Decode: this.decode, Encode: encode };
|
|
6681
|
-
return { ...
|
|
6603
|
+
return { ...schema, [TransformKind]: Codec };
|
|
6682
6604
|
}
|
|
6683
6605
|
Encode(encode) {
|
|
6684
6606
|
return IsTransform(this.schema) ? this.EncodeTransform(encode, this.schema) : this.EncodeSchema(encode, this.schema);
|
|
@@ -6937,7 +6859,7 @@ var init_esm = __esm({
|
|
|
6937
6859
|
init_required2();
|
|
6938
6860
|
init_rest2();
|
|
6939
6861
|
init_return_type2();
|
|
6940
|
-
|
|
6862
|
+
init_schema3();
|
|
6941
6863
|
init_static2();
|
|
6942
6864
|
init_string2();
|
|
6943
6865
|
init_symbol2();
|
|
@@ -6987,7 +6909,7 @@ var init_schemas = __esm({
|
|
|
6987
6909
|
});
|
|
6988
6910
|
|
|
6989
6911
|
// src/lib/contracts/auth.ts
|
|
6990
|
-
var EMAIL_PATTERN, PHONE_PATTERN, FINGERPRINT_PATTERN, UUID_PATTERN, BASE64_PATTERN, sendVerificationCodeContract, verifyCodeContract, checkAccountExistsContract, registerContract, loginContract, logoutContract, rotateKeyContract, changePasswordContract;
|
|
6912
|
+
var EMAIL_PATTERN, PHONE_PATTERN, FINGERPRINT_PATTERN, UUID_PATTERN, BASE64_PATTERN, sendVerificationCodeContract, verifyCodeContract, checkAccountExistsContract, registerContract, loginContract, logoutContract, rotateKeyContract, changePasswordContract, getMeContract;
|
|
6991
6913
|
var init_auth = __esm({
|
|
6992
6914
|
"src/lib/contracts/auth.ts"() {
|
|
6993
6915
|
"use strict";
|
|
@@ -7262,6 +7184,33 @@ var init_auth = __esm({
|
|
|
7262
7184
|
})
|
|
7263
7185
|
)
|
|
7264
7186
|
};
|
|
7187
|
+
getMeContract = {
|
|
7188
|
+
method: "GET",
|
|
7189
|
+
path: "/_auth/me",
|
|
7190
|
+
body: Type.Object({}),
|
|
7191
|
+
response: ApiResponseSchema(
|
|
7192
|
+
Type.Object({
|
|
7193
|
+
userId: Type.String({ description: "User ID" }),
|
|
7194
|
+
email: Type.Optional(Type.String({ description: "User email address" })),
|
|
7195
|
+
phone: Type.Optional(Type.String({ description: "User phone number" })),
|
|
7196
|
+
role: Type.Object({
|
|
7197
|
+
id: Type.Number({ description: "Role ID" }),
|
|
7198
|
+
name: Type.String({ description: "Role name (e.g., user, admin)" }),
|
|
7199
|
+
displayName: Type.String({ description: "Display name for UI" }),
|
|
7200
|
+
priority: Type.Number({ description: "Role priority level" })
|
|
7201
|
+
}, { description: "User role information" }),
|
|
7202
|
+
permissions: Type.Array(
|
|
7203
|
+
Type.Object({
|
|
7204
|
+
id: Type.Number({ description: "Permission ID" }),
|
|
7205
|
+
name: Type.String({ description: "Permission name (e.g., user:delete)" }),
|
|
7206
|
+
displayName: Type.String({ description: "Display name for UI" }),
|
|
7207
|
+
category: Type.Optional(Type.String({ description: "Permission category" }))
|
|
7208
|
+
}),
|
|
7209
|
+
{ description: "List of permissions granted through role" }
|
|
7210
|
+
)
|
|
7211
|
+
})
|
|
7212
|
+
)
|
|
7213
|
+
};
|
|
7265
7214
|
}
|
|
7266
7215
|
});
|
|
7267
7216
|
|
|
@@ -7514,9 +7463,55 @@ var init_contracts = __esm({
|
|
|
7514
7463
|
}
|
|
7515
7464
|
});
|
|
7516
7465
|
|
|
7466
|
+
// src/server/helpers/password.ts
|
|
7467
|
+
import bcrypt from "bcrypt";
|
|
7468
|
+
async function hashPassword(password) {
|
|
7469
|
+
if (!password || password.length === 0) {
|
|
7470
|
+
throw new Error("Password cannot be empty");
|
|
7471
|
+
}
|
|
7472
|
+
return bcrypt.hash(password, SALT_ROUNDS);
|
|
7473
|
+
}
|
|
7474
|
+
async function verifyPassword(password, hash) {
|
|
7475
|
+
if (!password || password.length === 0) {
|
|
7476
|
+
throw new Error("Password cannot be empty");
|
|
7477
|
+
}
|
|
7478
|
+
if (!hash || hash.length === 0) {
|
|
7479
|
+
throw new Error("Hash cannot be empty");
|
|
7480
|
+
}
|
|
7481
|
+
return bcrypt.compare(password, hash);
|
|
7482
|
+
}
|
|
7483
|
+
var SALT_ROUNDS;
|
|
7484
|
+
var init_password = __esm({
|
|
7485
|
+
"src/server/helpers/password.ts"() {
|
|
7486
|
+
"use strict";
|
|
7487
|
+
SALT_ROUNDS = parseInt(
|
|
7488
|
+
process.env.SPFN_AUTH_BCRYPT_SALT_ROUNDS || // New prefixed version (recommended)
|
|
7489
|
+
process.env.BCRYPT_SALT_ROUNDS || // Legacy fallback
|
|
7490
|
+
"10",
|
|
7491
|
+
10
|
|
7492
|
+
);
|
|
7493
|
+
}
|
|
7494
|
+
});
|
|
7495
|
+
|
|
7517
7496
|
// src/server/helpers/jwt.ts
|
|
7497
|
+
var jwt_exports = {};
|
|
7498
|
+
__export(jwt_exports, {
|
|
7499
|
+
decodeToken: () => decodeToken,
|
|
7500
|
+
generateToken: () => generateToken,
|
|
7501
|
+
verifyClientToken: () => verifyClientToken,
|
|
7502
|
+
verifyKeyFingerprint: () => verifyKeyFingerprint,
|
|
7503
|
+
verifyToken: () => verifyToken
|
|
7504
|
+
});
|
|
7518
7505
|
import jwt from "jsonwebtoken";
|
|
7519
7506
|
import crypto from "crypto";
|
|
7507
|
+
function generateToken(payload) {
|
|
7508
|
+
return jwt.sign(payload, JWT_SECRET, {
|
|
7509
|
+
expiresIn: JWT_EXPIRES_IN
|
|
7510
|
+
});
|
|
7511
|
+
}
|
|
7512
|
+
function verifyToken(token) {
|
|
7513
|
+
return jwt.verify(token, JWT_SECRET);
|
|
7514
|
+
}
|
|
7520
7515
|
function verifyClientToken(token, publicKeyB64, algorithm) {
|
|
7521
7516
|
try {
|
|
7522
7517
|
const publicKeyDER = Buffer.from(publicKeyB64, "base64");
|
|
@@ -7545,6 +7540,13 @@ function verifyClientToken(token, publicKeyB64, algorithm) {
|
|
|
7545
7540
|
throw new Error(`Token verification failed: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
7546
7541
|
}
|
|
7547
7542
|
}
|
|
7543
|
+
function decodeToken(token) {
|
|
7544
|
+
try {
|
|
7545
|
+
return jwt.decode(token);
|
|
7546
|
+
} catch {
|
|
7547
|
+
return null;
|
|
7548
|
+
}
|
|
7549
|
+
}
|
|
7548
7550
|
function verifyKeyFingerprint(publicKeyB64, expectedFingerprint) {
|
|
7549
7551
|
try {
|
|
7550
7552
|
const publicKeyDER = Buffer.from(publicKeyB64, "base64");
|
|
@@ -7568,6 +7570,146 @@ var init_jwt = __esm({
|
|
|
7568
7570
|
}
|
|
7569
7571
|
});
|
|
7570
7572
|
|
|
7573
|
+
// src/server/helpers/verification.ts
|
|
7574
|
+
import jwt2 from "jsonwebtoken";
|
|
7575
|
+
import { getDatabase as getDatabase2, create } from "@spfn/core/db";
|
|
7576
|
+
import { eq as eq2, and as and2 } from "drizzle-orm";
|
|
7577
|
+
function getVerificationTokenSecret() {
|
|
7578
|
+
const secret = process.env.SPFN_AUTH_VERIFICATION_TOKEN_SECRET || // New prefixed version (recommended)
|
|
7579
|
+
process.env.VERIFICATION_TOKEN_SECRET || // Legacy fallback
|
|
7580
|
+
process.env.SPFN_AUTH_JWT_SECRET || // New JWT secret fallback
|
|
7581
|
+
process.env.JWT_SECRET;
|
|
7582
|
+
if (!secret || secret.length < 32) {
|
|
7583
|
+
throw new Error("SPFN_AUTH_VERIFICATION_TOKEN_SECRET must be at least 32 characters long");
|
|
7584
|
+
}
|
|
7585
|
+
return secret;
|
|
7586
|
+
}
|
|
7587
|
+
function generateVerificationCode() {
|
|
7588
|
+
const code = Math.floor(Math.random() * 1e6).toString().padStart(6, "0");
|
|
7589
|
+
return code;
|
|
7590
|
+
}
|
|
7591
|
+
async function storeVerificationCode(target, targetType, code, purpose) {
|
|
7592
|
+
const db = getDatabase2();
|
|
7593
|
+
if (!db) {
|
|
7594
|
+
throw new Error("Database not initialized");
|
|
7595
|
+
}
|
|
7596
|
+
const expiresAt = /* @__PURE__ */ new Date();
|
|
7597
|
+
expiresAt.setMinutes(expiresAt.getMinutes() + VERIFICATION_CODE_EXPIRY_MINUTES);
|
|
7598
|
+
const record = await create(verificationCodes, {
|
|
7599
|
+
target,
|
|
7600
|
+
targetType,
|
|
7601
|
+
code,
|
|
7602
|
+
purpose,
|
|
7603
|
+
expiresAt,
|
|
7604
|
+
attempts: "0"
|
|
7605
|
+
});
|
|
7606
|
+
return record;
|
|
7607
|
+
}
|
|
7608
|
+
async function validateVerificationCode(target, targetType, code, purpose) {
|
|
7609
|
+
const db = getDatabase2();
|
|
7610
|
+
if (!db) {
|
|
7611
|
+
throw new Error("Database not initialized");
|
|
7612
|
+
}
|
|
7613
|
+
const records = await db.select().from(verificationCodes).where(
|
|
7614
|
+
and2(
|
|
7615
|
+
eq2(verificationCodes.target, target),
|
|
7616
|
+
eq2(verificationCodes.targetType, targetType),
|
|
7617
|
+
eq2(verificationCodes.code, code),
|
|
7618
|
+
eq2(verificationCodes.purpose, purpose)
|
|
7619
|
+
)
|
|
7620
|
+
).limit(1);
|
|
7621
|
+
if (records.length === 0) {
|
|
7622
|
+
return { valid: false, error: "Invalid verification code" };
|
|
7623
|
+
}
|
|
7624
|
+
const record = records[0];
|
|
7625
|
+
if (record.usedAt) {
|
|
7626
|
+
return { valid: false, error: "Verification code already used" };
|
|
7627
|
+
}
|
|
7628
|
+
if (/* @__PURE__ */ new Date() > new Date(record.expiresAt)) {
|
|
7629
|
+
return { valid: false, error: "Verification code expired" };
|
|
7630
|
+
}
|
|
7631
|
+
const attempts = parseInt(record.attempts, 10);
|
|
7632
|
+
if (attempts >= MAX_VERIFICATION_ATTEMPTS) {
|
|
7633
|
+
return { valid: false, error: "Too many attempts, please request a new code" };
|
|
7634
|
+
}
|
|
7635
|
+
await db.update(verificationCodes).set({ attempts: (attempts + 1).toString() }).where(eq2(verificationCodes.id, record.id));
|
|
7636
|
+
return { valid: true, codeId: record.id };
|
|
7637
|
+
}
|
|
7638
|
+
async function markCodeAsUsed(codeId) {
|
|
7639
|
+
const db = getDatabase2();
|
|
7640
|
+
if (!db) {
|
|
7641
|
+
throw new Error("Database not initialized");
|
|
7642
|
+
}
|
|
7643
|
+
await db.update(verificationCodes).set({ usedAt: /* @__PURE__ */ new Date() }).where(eq2(verificationCodes.id, codeId));
|
|
7644
|
+
}
|
|
7645
|
+
function createVerificationToken(payload) {
|
|
7646
|
+
const secret = getVerificationTokenSecret();
|
|
7647
|
+
return jwt2.sign(payload, secret, {
|
|
7648
|
+
expiresIn: VERIFICATION_TOKEN_EXPIRY,
|
|
7649
|
+
issuer: "spfn-auth",
|
|
7650
|
+
audience: "spfn-client"
|
|
7651
|
+
});
|
|
7652
|
+
}
|
|
7653
|
+
function validateVerificationToken(token) {
|
|
7654
|
+
try {
|
|
7655
|
+
const secret = getVerificationTokenSecret();
|
|
7656
|
+
const decoded = jwt2.verify(token, secret, {
|
|
7657
|
+
issuer: "spfn-auth",
|
|
7658
|
+
audience: "spfn-client"
|
|
7659
|
+
});
|
|
7660
|
+
if (typeof decoded === "object" && decoded !== null && "target" in decoded && "targetType" in decoded && "purpose" in decoded && "codeId" in decoded) {
|
|
7661
|
+
return decoded;
|
|
7662
|
+
}
|
|
7663
|
+
return null;
|
|
7664
|
+
} catch (error) {
|
|
7665
|
+
console.error("[validateVerificationToken] Error:", error);
|
|
7666
|
+
return null;
|
|
7667
|
+
}
|
|
7668
|
+
}
|
|
7669
|
+
async function sendVerificationEmail(email, code, purpose) {
|
|
7670
|
+
console.log(`[VERIFICATION EMAIL] To: ${email}, Code: ${code}, Purpose: ${purpose}`);
|
|
7671
|
+
}
|
|
7672
|
+
async function sendVerificationSMS(phone, code, purpose) {
|
|
7673
|
+
console.log(`[VERIFICATION SMS] To: ${phone}, Code: ${code}, Purpose: ${purpose}`);
|
|
7674
|
+
}
|
|
7675
|
+
var VERIFICATION_TOKEN_EXPIRY, VERIFICATION_CODE_EXPIRY_MINUTES, MAX_VERIFICATION_ATTEMPTS;
|
|
7676
|
+
var init_verification = __esm({
|
|
7677
|
+
"src/server/helpers/verification.ts"() {
|
|
7678
|
+
"use strict";
|
|
7679
|
+
init_verification_codes();
|
|
7680
|
+
VERIFICATION_TOKEN_EXPIRY = "15m";
|
|
7681
|
+
VERIFICATION_CODE_EXPIRY_MINUTES = 5;
|
|
7682
|
+
MAX_VERIFICATION_ATTEMPTS = 5;
|
|
7683
|
+
}
|
|
7684
|
+
});
|
|
7685
|
+
|
|
7686
|
+
// src/server/helpers/context.ts
|
|
7687
|
+
function getAuth(c) {
|
|
7688
|
+
if ("raw" in c && c.raw) {
|
|
7689
|
+
return c.raw.get("auth");
|
|
7690
|
+
}
|
|
7691
|
+
return c.get("auth");
|
|
7692
|
+
}
|
|
7693
|
+
function getUser(c) {
|
|
7694
|
+
return getAuth(c).user;
|
|
7695
|
+
}
|
|
7696
|
+
var init_context2 = __esm({
|
|
7697
|
+
"src/server/helpers/context.ts"() {
|
|
7698
|
+
"use strict";
|
|
7699
|
+
}
|
|
7700
|
+
});
|
|
7701
|
+
|
|
7702
|
+
// src/server/helpers/index.ts
|
|
7703
|
+
var init_helpers3 = __esm({
|
|
7704
|
+
"src/server/helpers/index.ts"() {
|
|
7705
|
+
"use strict";
|
|
7706
|
+
init_password();
|
|
7707
|
+
init_jwt();
|
|
7708
|
+
init_verification();
|
|
7709
|
+
init_context2();
|
|
7710
|
+
}
|
|
7711
|
+
});
|
|
7712
|
+
|
|
7571
7713
|
// src/server/errors/auth-errors.ts
|
|
7572
7714
|
import {
|
|
7573
7715
|
ValidationError,
|
|
@@ -7605,16 +7747,14 @@ var init_auth_errors = __esm({
|
|
|
7605
7747
|
};
|
|
7606
7748
|
AccountDisabledError = class extends ForbiddenError {
|
|
7607
7749
|
constructor(status = "disabled") {
|
|
7608
|
-
super(`Account is ${status}
|
|
7750
|
+
super(`Account is ${status}`, { details: { status } });
|
|
7609
7751
|
this.name = "AccountDisabledError";
|
|
7610
|
-
this.details = { status };
|
|
7611
7752
|
}
|
|
7612
7753
|
};
|
|
7613
7754
|
AccountAlreadyExistsError = class extends ConflictError {
|
|
7614
7755
|
constructor(identifier, identifierType) {
|
|
7615
|
-
super("Account already exists");
|
|
7756
|
+
super("Account already exists", { details: { identifier, identifierType } });
|
|
7616
7757
|
this.name = "AccountAlreadyExistsError";
|
|
7617
|
-
this.details = { identifier, identifierType };
|
|
7618
7758
|
}
|
|
7619
7759
|
};
|
|
7620
7760
|
InvalidVerificationCodeError = class extends ValidationError {
|
|
@@ -7637,9 +7777,8 @@ var init_auth_errors = __esm({
|
|
|
7637
7777
|
};
|
|
7638
7778
|
VerificationTokenPurposeMismatchError = class extends ValidationError {
|
|
7639
7779
|
constructor(expected, actual) {
|
|
7640
|
-
super(`Verification token is for ${actual}, but ${expected} was expected
|
|
7780
|
+
super(`Verification token is for ${actual}, but ${expected} was expected`, { details: { expected, actual } });
|
|
7641
7781
|
this.name = "VerificationTokenPurposeMismatchError";
|
|
7642
|
-
this.details = { expected, actual };
|
|
7643
7782
|
}
|
|
7644
7783
|
};
|
|
7645
7784
|
VerificationTokenTargetMismatchError = class extends ValidationError {
|
|
@@ -7659,287 +7798,9 @@ var init_errors = __esm({
|
|
|
7659
7798
|
}
|
|
7660
7799
|
});
|
|
7661
7800
|
|
|
7662
|
-
// src/server/middleware/authenticate.ts
|
|
7663
|
-
import { findOne, getDatabase as getDatabase2 } from "@spfn/core/db";
|
|
7664
|
-
import { UnauthorizedError as UnauthorizedError2 } from "@spfn/core/errors";
|
|
7665
|
-
import { eq as eq2, and as and2 } from "drizzle-orm";
|
|
7666
|
-
async function authenticate(c, next) {
|
|
7667
|
-
const authHeader = c.req.header("Authorization");
|
|
7668
|
-
const keyId = c.req.header("X-Key-Id");
|
|
7669
|
-
if (!authHeader || !authHeader.startsWith("Bearer ")) {
|
|
7670
|
-
throw new UnauthorizedError2("Missing or invalid authorization header");
|
|
7671
|
-
}
|
|
7672
|
-
if (!keyId) {
|
|
7673
|
-
throw new UnauthorizedError2("Missing X-Key-Id header");
|
|
7674
|
-
}
|
|
7675
|
-
const token = authHeader.substring(7);
|
|
7676
|
-
const db = getDatabase2();
|
|
7677
|
-
const [keyRecord] = await db.select().from(userPublicKeys).where(
|
|
7678
|
-
and2(
|
|
7679
|
-
eq2(userPublicKeys.keyId, keyId),
|
|
7680
|
-
eq2(userPublicKeys.isActive, true)
|
|
7681
|
-
)
|
|
7682
|
-
);
|
|
7683
|
-
if (!keyRecord) {
|
|
7684
|
-
throw new UnauthorizedError2("Invalid or revoked key");
|
|
7685
|
-
}
|
|
7686
|
-
if (keyRecord.expiresAt && /* @__PURE__ */ new Date() > keyRecord.expiresAt) {
|
|
7687
|
-
throw new KeyExpiredError();
|
|
7688
|
-
}
|
|
7689
|
-
try {
|
|
7690
|
-
verifyClientToken(
|
|
7691
|
-
token,
|
|
7692
|
-
keyRecord.publicKey,
|
|
7693
|
-
keyRecord.algorithm
|
|
7694
|
-
);
|
|
7695
|
-
} catch (err) {
|
|
7696
|
-
if (err instanceof Error) {
|
|
7697
|
-
if (err.name === "TokenExpiredError") {
|
|
7698
|
-
throw new TokenExpiredError();
|
|
7699
|
-
}
|
|
7700
|
-
if (err.name === "JsonWebTokenError") {
|
|
7701
|
-
throw new InvalidTokenError("Invalid token signature");
|
|
7702
|
-
}
|
|
7703
|
-
}
|
|
7704
|
-
throw new UnauthorizedError2("Authentication failed");
|
|
7705
|
-
}
|
|
7706
|
-
const user = await findOne(users, { id: keyRecord.userId });
|
|
7707
|
-
if (!user) {
|
|
7708
|
-
throw new UnauthorizedError2("User not found");
|
|
7709
|
-
}
|
|
7710
|
-
if (user.status !== "active") {
|
|
7711
|
-
throw new AccountDisabledError(user.status);
|
|
7712
|
-
}
|
|
7713
|
-
db.update(userPublicKeys).set({ lastUsedAt: /* @__PURE__ */ new Date() }).where(eq2(userPublicKeys.id, keyRecord.id)).execute().catch((err) => console.error("Failed to update lastUsedAt:", err));
|
|
7714
|
-
c.set("auth", {
|
|
7715
|
-
user,
|
|
7716
|
-
userId: String(user.id),
|
|
7717
|
-
keyId
|
|
7718
|
-
});
|
|
7719
|
-
await next();
|
|
7720
|
-
}
|
|
7721
|
-
var init_authenticate = __esm({
|
|
7722
|
-
"src/server/middleware/authenticate.ts"() {
|
|
7723
|
-
"use strict";
|
|
7724
|
-
init_jwt();
|
|
7725
|
-
init_entities();
|
|
7726
|
-
init_errors();
|
|
7727
|
-
}
|
|
7728
|
-
});
|
|
7729
|
-
|
|
7730
|
-
// src/server/helpers/context.ts
|
|
7731
|
-
function getAuth(c) {
|
|
7732
|
-
if ("raw" in c && c.raw) {
|
|
7733
|
-
return c.raw.get("auth");
|
|
7734
|
-
}
|
|
7735
|
-
return c.get("auth");
|
|
7736
|
-
}
|
|
7737
|
-
function getUser(c) {
|
|
7738
|
-
return getAuth(c).user;
|
|
7739
|
-
}
|
|
7740
|
-
var init_context2 = __esm({
|
|
7741
|
-
"src/server/helpers/context.ts"() {
|
|
7742
|
-
"use strict";
|
|
7743
|
-
}
|
|
7744
|
-
});
|
|
7745
|
-
|
|
7746
|
-
// src/server/services/permission.service.ts
|
|
7747
|
-
import { getDatabase as getDatabase3 } from "@spfn/core/db";
|
|
7748
|
-
import { eq as eq3, and as and3 } from "drizzle-orm";
|
|
7749
|
-
var init_permission_service = __esm({
|
|
7750
|
-
"src/server/services/permission.service.ts"() {
|
|
7751
|
-
"use strict";
|
|
7752
|
-
init_entities();
|
|
7753
|
-
}
|
|
7754
|
-
});
|
|
7755
|
-
|
|
7756
|
-
// src/server/middleware/require-permission.ts
|
|
7757
|
-
import { ForbiddenError as ForbiddenError2 } from "@spfn/core/errors";
|
|
7758
|
-
var init_require_permission = __esm({
|
|
7759
|
-
"src/server/middleware/require-permission.ts"() {
|
|
7760
|
-
"use strict";
|
|
7761
|
-
init_context2();
|
|
7762
|
-
init_permission_service();
|
|
7763
|
-
}
|
|
7764
|
-
});
|
|
7765
|
-
|
|
7766
|
-
// src/server/middleware/require-role.ts
|
|
7767
|
-
import { ForbiddenError as ForbiddenError3 } from "@spfn/core/errors";
|
|
7768
|
-
var init_require_role = __esm({
|
|
7769
|
-
"src/server/middleware/require-role.ts"() {
|
|
7770
|
-
"use strict";
|
|
7771
|
-
init_context2();
|
|
7772
|
-
init_permission_service();
|
|
7773
|
-
}
|
|
7774
|
-
});
|
|
7775
|
-
|
|
7776
|
-
// src/server/middleware/index.ts
|
|
7777
|
-
var init_middleware = __esm({
|
|
7778
|
-
"src/server/middleware/index.ts"() {
|
|
7779
|
-
"use strict";
|
|
7780
|
-
init_authenticate();
|
|
7781
|
-
init_require_permission();
|
|
7782
|
-
init_require_role();
|
|
7783
|
-
}
|
|
7784
|
-
});
|
|
7785
|
-
|
|
7786
|
-
// src/server/helpers/password.ts
|
|
7787
|
-
import bcrypt from "bcrypt";
|
|
7788
|
-
async function hashPassword(password) {
|
|
7789
|
-
if (!password || password.length === 0) {
|
|
7790
|
-
throw new Error("Password cannot be empty");
|
|
7791
|
-
}
|
|
7792
|
-
return bcrypt.hash(password, SALT_ROUNDS);
|
|
7793
|
-
}
|
|
7794
|
-
async function verifyPassword(password, hash) {
|
|
7795
|
-
if (!password || password.length === 0) {
|
|
7796
|
-
throw new Error("Password cannot be empty");
|
|
7797
|
-
}
|
|
7798
|
-
if (!hash || hash.length === 0) {
|
|
7799
|
-
throw new Error("Hash cannot be empty");
|
|
7800
|
-
}
|
|
7801
|
-
return bcrypt.compare(password, hash);
|
|
7802
|
-
}
|
|
7803
|
-
var SALT_ROUNDS;
|
|
7804
|
-
var init_password = __esm({
|
|
7805
|
-
"src/server/helpers/password.ts"() {
|
|
7806
|
-
"use strict";
|
|
7807
|
-
SALT_ROUNDS = parseInt(
|
|
7808
|
-
process.env.SPFN_AUTH_BCRYPT_SALT_ROUNDS || // New prefixed version (recommended)
|
|
7809
|
-
process.env.BCRYPT_SALT_ROUNDS || // Legacy fallback
|
|
7810
|
-
"10",
|
|
7811
|
-
10
|
|
7812
|
-
);
|
|
7813
|
-
}
|
|
7814
|
-
});
|
|
7815
|
-
|
|
7816
|
-
// src/server/helpers/verification.ts
|
|
7817
|
-
import jwt2 from "jsonwebtoken";
|
|
7818
|
-
import { getDatabase as getDatabase4, create } from "@spfn/core/db";
|
|
7819
|
-
import { eq as eq4, and as and4 } from "drizzle-orm";
|
|
7820
|
-
function getVerificationTokenSecret() {
|
|
7821
|
-
const secret = process.env.SPFN_AUTH_VERIFICATION_TOKEN_SECRET || // New prefixed version (recommended)
|
|
7822
|
-
process.env.VERIFICATION_TOKEN_SECRET || // Legacy fallback
|
|
7823
|
-
process.env.SPFN_AUTH_JWT_SECRET || // New JWT secret fallback
|
|
7824
|
-
process.env.JWT_SECRET;
|
|
7825
|
-
if (!secret || secret.length < 32) {
|
|
7826
|
-
throw new Error("SPFN_AUTH_VERIFICATION_TOKEN_SECRET must be at least 32 characters long");
|
|
7827
|
-
}
|
|
7828
|
-
return secret;
|
|
7829
|
-
}
|
|
7830
|
-
function generateVerificationCode() {
|
|
7831
|
-
const code = Math.floor(Math.random() * 1e6).toString().padStart(6, "0");
|
|
7832
|
-
return code;
|
|
7833
|
-
}
|
|
7834
|
-
async function storeVerificationCode(target, targetType, code, purpose) {
|
|
7835
|
-
const db = getDatabase4();
|
|
7836
|
-
if (!db) {
|
|
7837
|
-
throw new Error("Database not initialized");
|
|
7838
|
-
}
|
|
7839
|
-
const expiresAt = /* @__PURE__ */ new Date();
|
|
7840
|
-
expiresAt.setMinutes(expiresAt.getMinutes() + VERIFICATION_CODE_EXPIRY_MINUTES);
|
|
7841
|
-
const record = await create(verificationCodes, {
|
|
7842
|
-
target,
|
|
7843
|
-
targetType,
|
|
7844
|
-
code,
|
|
7845
|
-
purpose,
|
|
7846
|
-
expiresAt,
|
|
7847
|
-
attempts: "0"
|
|
7848
|
-
});
|
|
7849
|
-
return record;
|
|
7850
|
-
}
|
|
7851
|
-
async function validateVerificationCode(target, targetType, code, purpose) {
|
|
7852
|
-
const db = getDatabase4();
|
|
7853
|
-
if (!db) {
|
|
7854
|
-
throw new Error("Database not initialized");
|
|
7855
|
-
}
|
|
7856
|
-
const records = await db.select().from(verificationCodes).where(
|
|
7857
|
-
and4(
|
|
7858
|
-
eq4(verificationCodes.target, target),
|
|
7859
|
-
eq4(verificationCodes.targetType, targetType),
|
|
7860
|
-
eq4(verificationCodes.code, code),
|
|
7861
|
-
eq4(verificationCodes.purpose, purpose)
|
|
7862
|
-
)
|
|
7863
|
-
).limit(1);
|
|
7864
|
-
if (records.length === 0) {
|
|
7865
|
-
return { valid: false, error: "Invalid verification code" };
|
|
7866
|
-
}
|
|
7867
|
-
const record = records[0];
|
|
7868
|
-
if (record.usedAt) {
|
|
7869
|
-
return { valid: false, error: "Verification code already used" };
|
|
7870
|
-
}
|
|
7871
|
-
if (/* @__PURE__ */ new Date() > new Date(record.expiresAt)) {
|
|
7872
|
-
return { valid: false, error: "Verification code expired" };
|
|
7873
|
-
}
|
|
7874
|
-
const attempts = parseInt(record.attempts, 10);
|
|
7875
|
-
if (attempts >= MAX_VERIFICATION_ATTEMPTS) {
|
|
7876
|
-
return { valid: false, error: "Too many attempts, please request a new code" };
|
|
7877
|
-
}
|
|
7878
|
-
await db.update(verificationCodes).set({ attempts: (attempts + 1).toString() }).where(eq4(verificationCodes.id, record.id));
|
|
7879
|
-
return { valid: true, codeId: record.id };
|
|
7880
|
-
}
|
|
7881
|
-
async function markCodeAsUsed(codeId) {
|
|
7882
|
-
const db = getDatabase4();
|
|
7883
|
-
if (!db) {
|
|
7884
|
-
throw new Error("Database not initialized");
|
|
7885
|
-
}
|
|
7886
|
-
await db.update(verificationCodes).set({ usedAt: /* @__PURE__ */ new Date() }).where(eq4(verificationCodes.id, codeId));
|
|
7887
|
-
}
|
|
7888
|
-
function createVerificationToken(payload) {
|
|
7889
|
-
const secret = getVerificationTokenSecret();
|
|
7890
|
-
return jwt2.sign(payload, secret, {
|
|
7891
|
-
expiresIn: VERIFICATION_TOKEN_EXPIRY,
|
|
7892
|
-
issuer: "spfn-auth",
|
|
7893
|
-
audience: "spfn-client"
|
|
7894
|
-
});
|
|
7895
|
-
}
|
|
7896
|
-
function validateVerificationToken(token) {
|
|
7897
|
-
try {
|
|
7898
|
-
const secret = getVerificationTokenSecret();
|
|
7899
|
-
const decoded = jwt2.verify(token, secret, {
|
|
7900
|
-
issuer: "spfn-auth",
|
|
7901
|
-
audience: "spfn-client"
|
|
7902
|
-
});
|
|
7903
|
-
if (typeof decoded === "object" && decoded !== null && "target" in decoded && "targetType" in decoded && "purpose" in decoded && "codeId" in decoded) {
|
|
7904
|
-
return decoded;
|
|
7905
|
-
}
|
|
7906
|
-
return null;
|
|
7907
|
-
} catch (error) {
|
|
7908
|
-
console.error("[validateVerificationToken] Error:", error);
|
|
7909
|
-
return null;
|
|
7910
|
-
}
|
|
7911
|
-
}
|
|
7912
|
-
async function sendVerificationEmail(email, code, purpose) {
|
|
7913
|
-
console.log(`[VERIFICATION EMAIL] To: ${email}, Code: ${code}, Purpose: ${purpose}`);
|
|
7914
|
-
}
|
|
7915
|
-
async function sendVerificationSMS(phone, code, purpose) {
|
|
7916
|
-
console.log(`[VERIFICATION SMS] To: ${phone}, Code: ${code}, Purpose: ${purpose}`);
|
|
7917
|
-
}
|
|
7918
|
-
var VERIFICATION_TOKEN_EXPIRY, VERIFICATION_CODE_EXPIRY_MINUTES, MAX_VERIFICATION_ATTEMPTS;
|
|
7919
|
-
var init_verification = __esm({
|
|
7920
|
-
"src/server/helpers/verification.ts"() {
|
|
7921
|
-
"use strict";
|
|
7922
|
-
init_verification_codes();
|
|
7923
|
-
VERIFICATION_TOKEN_EXPIRY = "15m";
|
|
7924
|
-
VERIFICATION_CODE_EXPIRY_MINUTES = 5;
|
|
7925
|
-
MAX_VERIFICATION_ATTEMPTS = 5;
|
|
7926
|
-
}
|
|
7927
|
-
});
|
|
7928
|
-
|
|
7929
|
-
// src/server/helpers/index.ts
|
|
7930
|
-
var init_helpers3 = __esm({
|
|
7931
|
-
"src/server/helpers/index.ts"() {
|
|
7932
|
-
"use strict";
|
|
7933
|
-
init_password();
|
|
7934
|
-
init_jwt();
|
|
7935
|
-
init_verification();
|
|
7936
|
-
init_context2();
|
|
7937
|
-
}
|
|
7938
|
-
});
|
|
7939
|
-
|
|
7940
7801
|
// src/server/services/key.service.ts
|
|
7941
|
-
import { create as create2, getDatabase as
|
|
7942
|
-
import { eq as
|
|
7802
|
+
import { create as create2, getDatabase as getDatabase3 } from "@spfn/core/db";
|
|
7803
|
+
import { eq as eq3, and as and3 } from "drizzle-orm";
|
|
7943
7804
|
function getKeyExpiryDate() {
|
|
7944
7805
|
const expiresAt = /* @__PURE__ */ new Date();
|
|
7945
7806
|
expiresAt.setDate(expiresAt.getDate() + 90);
|
|
@@ -7968,15 +7829,15 @@ async function rotateKeyService(params) {
|
|
|
7968
7829
|
if (!isValidFingerprint) {
|
|
7969
7830
|
throw new InvalidKeyFingerprintError();
|
|
7970
7831
|
}
|
|
7971
|
-
const db =
|
|
7832
|
+
const db = getDatabase3();
|
|
7972
7833
|
await db.update(userPublicKeys).set({
|
|
7973
7834
|
isActive: false,
|
|
7974
7835
|
revokedAt: /* @__PURE__ */ new Date(),
|
|
7975
7836
|
revokedReason: "Replaced by key rotation"
|
|
7976
7837
|
}).where(
|
|
7977
|
-
|
|
7978
|
-
|
|
7979
|
-
|
|
7838
|
+
and3(
|
|
7839
|
+
eq3(userPublicKeys.keyId, oldKeyId),
|
|
7840
|
+
eq3(userPublicKeys.userId, userId)
|
|
7980
7841
|
)
|
|
7981
7842
|
);
|
|
7982
7843
|
await create2(userPublicKeys, {
|
|
@@ -7996,15 +7857,15 @@ async function rotateKeyService(params) {
|
|
|
7996
7857
|
}
|
|
7997
7858
|
async function revokeKeyService(params) {
|
|
7998
7859
|
const { userId, keyId, reason } = params;
|
|
7999
|
-
const db =
|
|
7860
|
+
const db = getDatabase3();
|
|
8000
7861
|
await db.update(userPublicKeys).set({
|
|
8001
7862
|
isActive: false,
|
|
8002
7863
|
revokedAt: /* @__PURE__ */ new Date(),
|
|
8003
7864
|
revokedReason: reason
|
|
8004
7865
|
}).where(
|
|
8005
|
-
|
|
8006
|
-
|
|
8007
|
-
|
|
7866
|
+
and3(
|
|
7867
|
+
eq3(userPublicKeys.keyId, keyId),
|
|
7868
|
+
eq3(userPublicKeys.userId, userId)
|
|
8008
7869
|
)
|
|
8009
7870
|
);
|
|
8010
7871
|
}
|
|
@@ -8018,7 +7879,7 @@ var init_key_service = __esm({
|
|
|
8018
7879
|
});
|
|
8019
7880
|
|
|
8020
7881
|
// src/server/services/user.service.ts
|
|
8021
|
-
import { findOne
|
|
7882
|
+
import { findOne, updateOne } from "@spfn/core/db";
|
|
8022
7883
|
async function updateLastLoginService(userId) {
|
|
8023
7884
|
await updateOne(users, { id: userId }, {
|
|
8024
7885
|
lastLoginAt: /* @__PURE__ */ new Date()
|
|
@@ -8044,14 +7905,14 @@ __export(role_service_exports, {
|
|
|
8044
7905
|
setRolePermissions: () => setRolePermissions,
|
|
8045
7906
|
updateRole: () => updateRole
|
|
8046
7907
|
});
|
|
8047
|
-
import { getDatabase as
|
|
8048
|
-
import { eq as
|
|
7908
|
+
import { getDatabase as getDatabase4 } from "@spfn/core/db";
|
|
7909
|
+
import { eq as eq4, and as and4 } from "drizzle-orm";
|
|
8049
7910
|
async function createRole(data) {
|
|
8050
|
-
const db =
|
|
7911
|
+
const db = getDatabase4();
|
|
8051
7912
|
if (!db) {
|
|
8052
7913
|
throw new Error("[Auth] Database not initialized");
|
|
8053
7914
|
}
|
|
8054
|
-
const existing = await db.select().from(roles).where(
|
|
7915
|
+
const existing = await db.select().from(roles).where(eq4(roles.name, data.name)).limit(1);
|
|
8055
7916
|
if (existing.length > 0) {
|
|
8056
7917
|
throw new Error(`Role with name '${data.name}' already exists`);
|
|
8057
7918
|
}
|
|
@@ -8075,28 +7936,28 @@ async function createRole(data) {
|
|
|
8075
7936
|
return newRole;
|
|
8076
7937
|
}
|
|
8077
7938
|
async function updateRole(roleId, data) {
|
|
8078
|
-
const db =
|
|
7939
|
+
const db = getDatabase4();
|
|
8079
7940
|
if (!db) {
|
|
8080
7941
|
throw new Error("[Auth] Database not initialized");
|
|
8081
7942
|
}
|
|
8082
7943
|
const roleIdNum = Number(roleId);
|
|
8083
|
-
const [role] = await db.select().from(roles).where(
|
|
7944
|
+
const [role] = await db.select().from(roles).where(eq4(roles.id, roleIdNum)).limit(1);
|
|
8084
7945
|
if (!role) {
|
|
8085
7946
|
throw new Error("Role not found");
|
|
8086
7947
|
}
|
|
8087
7948
|
if (role.isBuiltin && data.priority !== void 0) {
|
|
8088
7949
|
throw new Error("Cannot modify priority of built-in roles");
|
|
8089
7950
|
}
|
|
8090
|
-
const [updated] = await db.update(roles).set(data).where(
|
|
7951
|
+
const [updated] = await db.update(roles).set(data).where(eq4(roles.id, roleIdNum)).returning();
|
|
8091
7952
|
return updated;
|
|
8092
7953
|
}
|
|
8093
7954
|
async function deleteRole(roleId) {
|
|
8094
|
-
const db =
|
|
7955
|
+
const db = getDatabase4();
|
|
8095
7956
|
if (!db) {
|
|
8096
7957
|
throw new Error("[Auth] Database not initialized");
|
|
8097
7958
|
}
|
|
8098
7959
|
const roleIdNum = Number(roleId);
|
|
8099
|
-
const [role] = await db.select().from(roles).where(
|
|
7960
|
+
const [role] = await db.select().from(roles).where(eq4(roles.id, roleIdNum)).limit(1);
|
|
8100
7961
|
if (!role) {
|
|
8101
7962
|
throw new Error("Role not found");
|
|
8102
7963
|
}
|
|
@@ -8106,20 +7967,20 @@ async function deleteRole(roleId) {
|
|
|
8106
7967
|
if (role.isSystem) {
|
|
8107
7968
|
throw new Error(`Cannot delete system role: ${role.name}. Deactivate it instead.`);
|
|
8108
7969
|
}
|
|
8109
|
-
await db.delete(roles).where(
|
|
7970
|
+
await db.delete(roles).where(eq4(roles.id, roleIdNum));
|
|
8110
7971
|
console.log(`[Auth] \u{1F5D1}\uFE0F Deleted role: ${role.name}`);
|
|
8111
7972
|
}
|
|
8112
7973
|
async function addPermissionToRole(roleId, permissionId) {
|
|
8113
|
-
const db =
|
|
7974
|
+
const db = getDatabase4();
|
|
8114
7975
|
if (!db) {
|
|
8115
7976
|
throw new Error("[Auth] Database not initialized");
|
|
8116
7977
|
}
|
|
8117
7978
|
const roleIdNum = Number(roleId);
|
|
8118
7979
|
const permissionIdNum = Number(permissionId);
|
|
8119
7980
|
const existing = await db.select().from(rolePermissions).where(
|
|
8120
|
-
|
|
8121
|
-
|
|
8122
|
-
|
|
7981
|
+
and4(
|
|
7982
|
+
eq4(rolePermissions.roleId, roleIdNum),
|
|
7983
|
+
eq4(rolePermissions.permissionId, permissionIdNum)
|
|
8123
7984
|
)
|
|
8124
7985
|
).limit(1);
|
|
8125
7986
|
if (existing.length > 0) {
|
|
@@ -8131,26 +7992,26 @@ async function addPermissionToRole(roleId, permissionId) {
|
|
|
8131
7992
|
});
|
|
8132
7993
|
}
|
|
8133
7994
|
async function removePermissionFromRole(roleId, permissionId) {
|
|
8134
|
-
const db =
|
|
7995
|
+
const db = getDatabase4();
|
|
8135
7996
|
if (!db) {
|
|
8136
7997
|
throw new Error("[Auth] Database not initialized");
|
|
8137
7998
|
}
|
|
8138
7999
|
const roleIdNum = Number(roleId);
|
|
8139
8000
|
const permissionIdNum = Number(permissionId);
|
|
8140
8001
|
await db.delete(rolePermissions).where(
|
|
8141
|
-
|
|
8142
|
-
|
|
8143
|
-
|
|
8002
|
+
and4(
|
|
8003
|
+
eq4(rolePermissions.roleId, roleIdNum),
|
|
8004
|
+
eq4(rolePermissions.permissionId, permissionIdNum)
|
|
8144
8005
|
)
|
|
8145
8006
|
);
|
|
8146
8007
|
}
|
|
8147
8008
|
async function setRolePermissions(roleId, permissionIds) {
|
|
8148
|
-
const db =
|
|
8009
|
+
const db = getDatabase4();
|
|
8149
8010
|
if (!db) {
|
|
8150
8011
|
throw new Error("[Auth] Database not initialized");
|
|
8151
8012
|
}
|
|
8152
8013
|
const roleIdNum = Number(roleId);
|
|
8153
|
-
await db.delete(rolePermissions).where(
|
|
8014
|
+
await db.delete(rolePermissions).where(eq4(rolePermissions.roleId, roleIdNum));
|
|
8154
8015
|
if (permissionIds.length > 0) {
|
|
8155
8016
|
const mappings = permissionIds.map((permId) => ({
|
|
8156
8017
|
roleId: roleIdNum,
|
|
@@ -8160,31 +8021,31 @@ async function setRolePermissions(roleId, permissionIds) {
|
|
|
8160
8021
|
}
|
|
8161
8022
|
}
|
|
8162
8023
|
async function getAllRoles(includeInactive = false) {
|
|
8163
|
-
const db =
|
|
8024
|
+
const db = getDatabase4();
|
|
8164
8025
|
if (!db) {
|
|
8165
8026
|
throw new Error("[Auth] Database not initialized");
|
|
8166
8027
|
}
|
|
8167
8028
|
const query = db.select().from(roles);
|
|
8168
8029
|
if (!includeInactive) {
|
|
8169
|
-
return query.where(
|
|
8030
|
+
return query.where(eq4(roles.isActive, true));
|
|
8170
8031
|
}
|
|
8171
8032
|
return query;
|
|
8172
8033
|
}
|
|
8173
8034
|
async function getRoleByName(name) {
|
|
8174
|
-
const db =
|
|
8035
|
+
const db = getDatabase4();
|
|
8175
8036
|
if (!db) {
|
|
8176
8037
|
throw new Error("[Auth] Database not initialized");
|
|
8177
8038
|
}
|
|
8178
|
-
const [role] = await db.select().from(roles).where(
|
|
8039
|
+
const [role] = await db.select().from(roles).where(eq4(roles.name, name)).limit(1);
|
|
8179
8040
|
return role || null;
|
|
8180
8041
|
}
|
|
8181
8042
|
async function getRolePermissions(roleId) {
|
|
8182
|
-
const db =
|
|
8043
|
+
const db = getDatabase4();
|
|
8183
8044
|
if (!db) {
|
|
8184
8045
|
throw new Error("[Auth] Database not initialized");
|
|
8185
8046
|
}
|
|
8186
8047
|
const roleIdNum = Number(roleId);
|
|
8187
|
-
const perms = await db.select({ name: permissions.name }).from(rolePermissions).innerJoin(permissions,
|
|
8048
|
+
const perms = await db.select({ name: permissions.name }).from(rolePermissions).innerJoin(permissions, eq4(rolePermissions.permissionId, permissions.id)).where(eq4(rolePermissions.roleId, roleIdNum));
|
|
8188
8049
|
return perms.map((p) => p.name);
|
|
8189
8050
|
}
|
|
8190
8051
|
var init_role_service = __esm({
|
|
@@ -8195,7 +8056,7 @@ var init_role_service = __esm({
|
|
|
8195
8056
|
});
|
|
8196
8057
|
|
|
8197
8058
|
// src/server/services/auth.service.ts
|
|
8198
|
-
import { findOne as
|
|
8059
|
+
import { findOne as findOne2, create as create3 } from "@spfn/core/db";
|
|
8199
8060
|
import { ValidationError as ValidationError2 } from "@spfn/core/errors";
|
|
8200
8061
|
async function checkAccountExistsService(params) {
|
|
8201
8062
|
const { email, phone } = params;
|
|
@@ -8205,11 +8066,11 @@ async function checkAccountExistsService(params) {
|
|
|
8205
8066
|
if (email) {
|
|
8206
8067
|
identifier = email;
|
|
8207
8068
|
identifierType = "email";
|
|
8208
|
-
user = await
|
|
8069
|
+
user = await findOne2(users, { email });
|
|
8209
8070
|
} else if (phone) {
|
|
8210
8071
|
identifier = phone;
|
|
8211
8072
|
identifierType = "phone";
|
|
8212
|
-
user = await
|
|
8073
|
+
user = await findOne2(users, { phone });
|
|
8213
8074
|
} else {
|
|
8214
8075
|
throw new ValidationError2("Either email or phone must be provided");
|
|
8215
8076
|
}
|
|
@@ -8238,9 +8099,9 @@ async function registerService(params) {
|
|
|
8238
8099
|
}
|
|
8239
8100
|
let existingUser;
|
|
8240
8101
|
if (email) {
|
|
8241
|
-
existingUser = await
|
|
8102
|
+
existingUser = await findOne2(users, { email });
|
|
8242
8103
|
} else if (phone) {
|
|
8243
|
-
existingUser = await
|
|
8104
|
+
existingUser = await findOne2(users, { phone });
|
|
8244
8105
|
} else {
|
|
8245
8106
|
throw new ValidationError2("Either email or phone must be provided");
|
|
8246
8107
|
}
|
|
@@ -8281,9 +8142,9 @@ async function loginService(params) {
|
|
|
8281
8142
|
const { email, phone, password, publicKey, keyId, fingerprint, oldKeyId, algorithm } = params;
|
|
8282
8143
|
let user;
|
|
8283
8144
|
if (email) {
|
|
8284
|
-
user = await
|
|
8145
|
+
user = await findOne2(users, { email });
|
|
8285
8146
|
} else if (phone) {
|
|
8286
|
-
user = await
|
|
8147
|
+
user = await findOne2(users, { phone });
|
|
8287
8148
|
} else {
|
|
8288
8149
|
throw new ValidationError2("Either email or phone must be provided");
|
|
8289
8150
|
}
|
|
@@ -8333,7 +8194,7 @@ async function changePasswordService(params) {
|
|
|
8333
8194
|
if (providedHash) {
|
|
8334
8195
|
passwordHash = providedHash;
|
|
8335
8196
|
} else {
|
|
8336
|
-
const user = await
|
|
8197
|
+
const user = await findOne2(users, { id: userId });
|
|
8337
8198
|
if (!user) {
|
|
8338
8199
|
throw new ValidationError2("User not found");
|
|
8339
8200
|
}
|
|
@@ -8407,6 +8268,136 @@ var init_verification_service = __esm({
|
|
|
8407
8268
|
}
|
|
8408
8269
|
});
|
|
8409
8270
|
|
|
8271
|
+
// src/server/services/me.service.ts
|
|
8272
|
+
import { getDatabase as getDatabase5 } from "@spfn/core/db";
|
|
8273
|
+
import { eq as eq5, and as and5 } from "drizzle-orm";
|
|
8274
|
+
async function getMeService(userId) {
|
|
8275
|
+
const db = getDatabase5();
|
|
8276
|
+
if (!db) {
|
|
8277
|
+
throw new Error("[Auth] Database not initialized");
|
|
8278
|
+
}
|
|
8279
|
+
const userIdNum = typeof userId === "string" ? Number(userId) : Number(userId);
|
|
8280
|
+
const [userWithRole] = await db.select({
|
|
8281
|
+
userId: users.id,
|
|
8282
|
+
email: users.email,
|
|
8283
|
+
phone: users.phone,
|
|
8284
|
+
roleId: roles.id,
|
|
8285
|
+
roleName: roles.name,
|
|
8286
|
+
roleDisplayName: roles.displayName,
|
|
8287
|
+
rolePriority: roles.priority
|
|
8288
|
+
}).from(users).innerJoin(roles, eq5(users.roleId, roles.id)).where(eq5(users.id, userIdNum)).limit(1);
|
|
8289
|
+
if (!userWithRole) {
|
|
8290
|
+
throw new Error("[Auth] User not found");
|
|
8291
|
+
}
|
|
8292
|
+
const rolePerms = await db.select({
|
|
8293
|
+
id: permissions.id,
|
|
8294
|
+
name: permissions.name,
|
|
8295
|
+
displayName: permissions.displayName,
|
|
8296
|
+
category: permissions.category
|
|
8297
|
+
}).from(rolePermissions).innerJoin(permissions, eq5(rolePermissions.permissionId, permissions.id)).where(
|
|
8298
|
+
and5(
|
|
8299
|
+
eq5(rolePermissions.roleId, userWithRole.roleId),
|
|
8300
|
+
eq5(permissions.isActive, true)
|
|
8301
|
+
)
|
|
8302
|
+
);
|
|
8303
|
+
return {
|
|
8304
|
+
userId: userWithRole.userId.toString(),
|
|
8305
|
+
email: userWithRole.email ?? void 0,
|
|
8306
|
+
phone: userWithRole.phone ?? void 0,
|
|
8307
|
+
role: {
|
|
8308
|
+
id: userWithRole.roleId,
|
|
8309
|
+
name: userWithRole.roleName,
|
|
8310
|
+
displayName: userWithRole.roleDisplayName,
|
|
8311
|
+
priority: userWithRole.rolePriority
|
|
8312
|
+
},
|
|
8313
|
+
permissions: rolePerms.map((perm) => ({
|
|
8314
|
+
id: perm.id,
|
|
8315
|
+
name: perm.name,
|
|
8316
|
+
displayName: perm.displayName,
|
|
8317
|
+
category: perm.category ?? void 0
|
|
8318
|
+
}))
|
|
8319
|
+
};
|
|
8320
|
+
}
|
|
8321
|
+
var init_me_service = __esm({
|
|
8322
|
+
"src/server/services/me.service.ts"() {
|
|
8323
|
+
"use strict";
|
|
8324
|
+
init_entities();
|
|
8325
|
+
}
|
|
8326
|
+
});
|
|
8327
|
+
|
|
8328
|
+
// src/server/services/permission.service.ts
|
|
8329
|
+
import { getDatabase as getDatabase6 } from "@spfn/core/db";
|
|
8330
|
+
import { eq as eq6, and as and6 } from "drizzle-orm";
|
|
8331
|
+
async function getUserPermissions(userId) {
|
|
8332
|
+
const db = getDatabase6();
|
|
8333
|
+
if (!db) {
|
|
8334
|
+
throw new Error("[Auth] Database not initialized");
|
|
8335
|
+
}
|
|
8336
|
+
const userIdNum = typeof userId === "string" ? Number(userId) : Number(userId);
|
|
8337
|
+
const [user] = await db.select({ roleId: users.roleId }).from(users).where(eq6(users.id, userIdNum)).limit(1);
|
|
8338
|
+
if (!user || !user.roleId) {
|
|
8339
|
+
return [];
|
|
8340
|
+
}
|
|
8341
|
+
const permSet = /* @__PURE__ */ new Set();
|
|
8342
|
+
const rolePerms = await db.select({ name: permissions.name }).from(rolePermissions).innerJoin(permissions, eq6(rolePermissions.permissionId, permissions.id)).where(
|
|
8343
|
+
and6(
|
|
8344
|
+
eq6(rolePermissions.roleId, user.roleId),
|
|
8345
|
+
eq6(permissions.isActive, true)
|
|
8346
|
+
)
|
|
8347
|
+
);
|
|
8348
|
+
for (const perm of rolePerms) {
|
|
8349
|
+
permSet.add(perm.name);
|
|
8350
|
+
}
|
|
8351
|
+
const userPerms = await db.select({
|
|
8352
|
+
name: permissions.name,
|
|
8353
|
+
granted: userPermissions.granted,
|
|
8354
|
+
expiresAt: userPermissions.expiresAt
|
|
8355
|
+
}).from(userPermissions).innerJoin(permissions, eq6(userPermissions.permissionId, permissions.id)).where(eq6(userPermissions.userId, userIdNum));
|
|
8356
|
+
const now = /* @__PURE__ */ new Date();
|
|
8357
|
+
for (const userPerm of userPerms) {
|
|
8358
|
+
if (userPerm.expiresAt && userPerm.expiresAt < now) {
|
|
8359
|
+
continue;
|
|
8360
|
+
}
|
|
8361
|
+
if (userPerm.granted) {
|
|
8362
|
+
permSet.add(userPerm.name);
|
|
8363
|
+
} else {
|
|
8364
|
+
permSet.delete(userPerm.name);
|
|
8365
|
+
}
|
|
8366
|
+
}
|
|
8367
|
+
return Array.from(permSet);
|
|
8368
|
+
}
|
|
8369
|
+
async function hasAllPermissions(userId, permissionNames) {
|
|
8370
|
+
const perms = await getUserPermissions(userId);
|
|
8371
|
+
return permissionNames.every((p) => perms.includes(p));
|
|
8372
|
+
}
|
|
8373
|
+
async function hasRole(userId, roleName) {
|
|
8374
|
+
const db = getDatabase6();
|
|
8375
|
+
if (!db) {
|
|
8376
|
+
throw new Error("[Auth] Database not initialized");
|
|
8377
|
+
}
|
|
8378
|
+
const userIdNum = typeof userId === "string" ? Number(userId) : Number(userId);
|
|
8379
|
+
const [user] = await db.select({ roleId: users.roleId }).from(users).where(eq6(users.id, userIdNum)).limit(1);
|
|
8380
|
+
if (!user || !user.roleId) {
|
|
8381
|
+
return false;
|
|
8382
|
+
}
|
|
8383
|
+
const [role] = await db.select({ name: roles.name }).from(roles).where(eq6(roles.id, user.roleId)).limit(1);
|
|
8384
|
+
return role?.name === roleName;
|
|
8385
|
+
}
|
|
8386
|
+
async function hasAnyRole(userId, roleNames) {
|
|
8387
|
+
for (const roleName of roleNames) {
|
|
8388
|
+
if (await hasRole(userId, roleName)) {
|
|
8389
|
+
return true;
|
|
8390
|
+
}
|
|
8391
|
+
}
|
|
8392
|
+
return false;
|
|
8393
|
+
}
|
|
8394
|
+
var init_permission_service = __esm({
|
|
8395
|
+
"src/server/services/permission.service.ts"() {
|
|
8396
|
+
"use strict";
|
|
8397
|
+
init_entities();
|
|
8398
|
+
}
|
|
8399
|
+
});
|
|
8400
|
+
|
|
8410
8401
|
// src/server/services/invitation.service.ts
|
|
8411
8402
|
import { getDatabase as getDatabase7 } from "@spfn/core/db";
|
|
8412
8403
|
import { eq as eq7, and as and7, lt, desc, sql as sql2 } from "drizzle-orm";
|
|
@@ -8685,6 +8676,7 @@ var init_services = __esm({
|
|
|
8685
8676
|
init_verification_service();
|
|
8686
8677
|
init_key_service();
|
|
8687
8678
|
init_user_service();
|
|
8679
|
+
init_me_service();
|
|
8688
8680
|
init_rbac_service();
|
|
8689
8681
|
init_permission_service();
|
|
8690
8682
|
init_role_service();
|
|
@@ -8699,7 +8691,6 @@ var init_auth2 = __esm({
|
|
|
8699
8691
|
"src/server/routes/auth/index.ts"() {
|
|
8700
8692
|
"use strict";
|
|
8701
8693
|
init_contracts();
|
|
8702
|
-
init_middleware();
|
|
8703
8694
|
init_helpers3();
|
|
8704
8695
|
init_services();
|
|
8705
8696
|
app = createApp();
|
|
@@ -8728,12 +8719,16 @@ var init_auth2 = __esm({
|
|
|
8728
8719
|
const result = await loginService(body);
|
|
8729
8720
|
return c.success(result);
|
|
8730
8721
|
});
|
|
8731
|
-
app.bind(logoutContract,
|
|
8732
|
-
const
|
|
8722
|
+
app.bind(logoutContract, async (c) => {
|
|
8723
|
+
const auth = getAuth(c);
|
|
8724
|
+
if (!auth) {
|
|
8725
|
+
return c.success({ success: true });
|
|
8726
|
+
}
|
|
8727
|
+
const { keyId, userId } = auth;
|
|
8733
8728
|
await logoutService({ userId: Number(userId), keyId });
|
|
8734
8729
|
return c.success({ success: true });
|
|
8735
8730
|
});
|
|
8736
|
-
app.bind(rotateKeyContract,
|
|
8731
|
+
app.bind(rotateKeyContract, async (c) => {
|
|
8737
8732
|
const body = await c.data();
|
|
8738
8733
|
const { keyId: oldKeyId, userId } = getAuth(c);
|
|
8739
8734
|
const result = await rotateKeyService({
|
|
@@ -8746,7 +8741,7 @@ var init_auth2 = __esm({
|
|
|
8746
8741
|
});
|
|
8747
8742
|
return c.success(result);
|
|
8748
8743
|
});
|
|
8749
|
-
app.bind(changePasswordContract,
|
|
8744
|
+
app.bind(changePasswordContract, async (c) => {
|
|
8750
8745
|
const body = await c.data();
|
|
8751
8746
|
const user = getUser(c);
|
|
8752
8747
|
await changePasswordService({
|
|
@@ -8757,10 +8752,147 @@ var init_auth2 = __esm({
|
|
|
8757
8752
|
});
|
|
8758
8753
|
return c.success({ success: true });
|
|
8759
8754
|
});
|
|
8755
|
+
app.bind(getMeContract, async (c) => {
|
|
8756
|
+
const { userId } = getAuth(c);
|
|
8757
|
+
const result = await getMeService(userId);
|
|
8758
|
+
return c.success(result);
|
|
8759
|
+
});
|
|
8760
8760
|
auth_default = app;
|
|
8761
8761
|
}
|
|
8762
8762
|
});
|
|
8763
8763
|
|
|
8764
|
+
// src/server/middleware/authenticate.ts
|
|
8765
|
+
import { findOne as findOne3, getDatabase as getDatabase8 } from "@spfn/core/db";
|
|
8766
|
+
import { UnauthorizedError as UnauthorizedError2 } from "@spfn/core/errors";
|
|
8767
|
+
import { eq as eq8, and as and8 } from "drizzle-orm";
|
|
8768
|
+
async function authenticate(c, next) {
|
|
8769
|
+
const authHeader = c.req.header("Authorization");
|
|
8770
|
+
if (!authHeader || !authHeader.startsWith("Bearer ")) {
|
|
8771
|
+
throw new UnauthorizedError2("Missing or invalid authorization header");
|
|
8772
|
+
}
|
|
8773
|
+
const token = authHeader.substring(7);
|
|
8774
|
+
const { decodeToken: decodeToken2 } = await Promise.resolve().then(() => (init_jwt(), jwt_exports));
|
|
8775
|
+
const decoded = decodeToken2(token);
|
|
8776
|
+
if (!decoded || !decoded.keyId) {
|
|
8777
|
+
throw new UnauthorizedError2("Invalid token: missing keyId");
|
|
8778
|
+
}
|
|
8779
|
+
const keyId = decoded.keyId;
|
|
8780
|
+
const db = getDatabase8();
|
|
8781
|
+
const [keyRecord] = await db.select().from(userPublicKeys).where(
|
|
8782
|
+
and8(
|
|
8783
|
+
eq8(userPublicKeys.keyId, keyId),
|
|
8784
|
+
eq8(userPublicKeys.isActive, true)
|
|
8785
|
+
)
|
|
8786
|
+
);
|
|
8787
|
+
if (!keyRecord) {
|
|
8788
|
+
throw new UnauthorizedError2("Invalid or revoked key");
|
|
8789
|
+
}
|
|
8790
|
+
if (keyRecord.expiresAt && /* @__PURE__ */ new Date() > keyRecord.expiresAt) {
|
|
8791
|
+
throw new KeyExpiredError();
|
|
8792
|
+
}
|
|
8793
|
+
try {
|
|
8794
|
+
verifyClientToken(
|
|
8795
|
+
token,
|
|
8796
|
+
keyRecord.publicKey,
|
|
8797
|
+
keyRecord.algorithm
|
|
8798
|
+
);
|
|
8799
|
+
} catch (err) {
|
|
8800
|
+
if (err instanceof Error) {
|
|
8801
|
+
if (err.name === "TokenExpiredError") {
|
|
8802
|
+
throw new TokenExpiredError();
|
|
8803
|
+
}
|
|
8804
|
+
if (err.name === "JsonWebTokenError") {
|
|
8805
|
+
throw new InvalidTokenError("Invalid token signature");
|
|
8806
|
+
}
|
|
8807
|
+
}
|
|
8808
|
+
throw new UnauthorizedError2("Authentication failed");
|
|
8809
|
+
}
|
|
8810
|
+
const user = await findOne3(users, { id: keyRecord.userId });
|
|
8811
|
+
if (!user) {
|
|
8812
|
+
throw new UnauthorizedError2("User not found");
|
|
8813
|
+
}
|
|
8814
|
+
if (user.status !== "active") {
|
|
8815
|
+
throw new AccountDisabledError(user.status);
|
|
8816
|
+
}
|
|
8817
|
+
db.update(userPublicKeys).set({ lastUsedAt: /* @__PURE__ */ new Date() }).where(eq8(userPublicKeys.id, keyRecord.id)).execute().catch((err) => console.error("Failed to update lastUsedAt:", err));
|
|
8818
|
+
c.set("auth", {
|
|
8819
|
+
user,
|
|
8820
|
+
userId: String(user.id),
|
|
8821
|
+
keyId
|
|
8822
|
+
});
|
|
8823
|
+
await next();
|
|
8824
|
+
}
|
|
8825
|
+
var init_authenticate = __esm({
|
|
8826
|
+
"src/server/middleware/authenticate.ts"() {
|
|
8827
|
+
"use strict";
|
|
8828
|
+
init_jwt();
|
|
8829
|
+
init_entities();
|
|
8830
|
+
init_errors();
|
|
8831
|
+
}
|
|
8832
|
+
});
|
|
8833
|
+
|
|
8834
|
+
// src/server/middleware/require-permission.ts
|
|
8835
|
+
import { ForbiddenError as ForbiddenError2 } from "@spfn/core/errors";
|
|
8836
|
+
function requirePermissions(...permissionNames) {
|
|
8837
|
+
return async (c, next) => {
|
|
8838
|
+
const auth = getAuth(c);
|
|
8839
|
+
if (!auth) {
|
|
8840
|
+
throw new ForbiddenError2("Authentication required");
|
|
8841
|
+
}
|
|
8842
|
+
const { userId } = auth;
|
|
8843
|
+
const allowed = await hasAllPermissions(userId, permissionNames);
|
|
8844
|
+
if (!allowed) {
|
|
8845
|
+
throw new ForbiddenError2(
|
|
8846
|
+
`Missing required permissions: ${permissionNames.join(", ")}`
|
|
8847
|
+
);
|
|
8848
|
+
}
|
|
8849
|
+
await next();
|
|
8850
|
+
};
|
|
8851
|
+
}
|
|
8852
|
+
var init_require_permission = __esm({
|
|
8853
|
+
"src/server/middleware/require-permission.ts"() {
|
|
8854
|
+
"use strict";
|
|
8855
|
+
init_context2();
|
|
8856
|
+
init_permission_service();
|
|
8857
|
+
}
|
|
8858
|
+
});
|
|
8859
|
+
|
|
8860
|
+
// src/server/middleware/require-role.ts
|
|
8861
|
+
import { ForbiddenError as ForbiddenError3 } from "@spfn/core/errors";
|
|
8862
|
+
function requireRole(...roleNames) {
|
|
8863
|
+
return async (c, next) => {
|
|
8864
|
+
const auth = getAuth(c);
|
|
8865
|
+
if (!auth) {
|
|
8866
|
+
throw new ForbiddenError3("Authentication required");
|
|
8867
|
+
}
|
|
8868
|
+
const { userId } = auth;
|
|
8869
|
+
const allowed = await hasAnyRole(userId, roleNames);
|
|
8870
|
+
if (!allowed) {
|
|
8871
|
+
throw new ForbiddenError3(
|
|
8872
|
+
`Required roles: ${roleNames.join(", ")}`
|
|
8873
|
+
);
|
|
8874
|
+
}
|
|
8875
|
+
await next();
|
|
8876
|
+
};
|
|
8877
|
+
}
|
|
8878
|
+
var init_require_role = __esm({
|
|
8879
|
+
"src/server/middleware/require-role.ts"() {
|
|
8880
|
+
"use strict";
|
|
8881
|
+
init_context2();
|
|
8882
|
+
init_permission_service();
|
|
8883
|
+
}
|
|
8884
|
+
});
|
|
8885
|
+
|
|
8886
|
+
// src/server/middleware/index.ts
|
|
8887
|
+
var init_middleware = __esm({
|
|
8888
|
+
"src/server/middleware/index.ts"() {
|
|
8889
|
+
"use strict";
|
|
8890
|
+
init_authenticate();
|
|
8891
|
+
init_require_permission();
|
|
8892
|
+
init_require_role();
|
|
8893
|
+
}
|
|
8894
|
+
});
|
|
8895
|
+
|
|
8764
8896
|
// src/server/routes/invitations/index.ts
|
|
8765
8897
|
import { createApp as createApp2 } from "@spfn/core/route";
|
|
8766
8898
|
var app2, invitations_default;
|
|
@@ -8804,7 +8936,7 @@ var init_invitations2 = __esm({
|
|
|
8804
8936
|
});
|
|
8805
8937
|
return c.success(result);
|
|
8806
8938
|
});
|
|
8807
|
-
app2.bind(createInvitationContract, [authenticate], async (c) => {
|
|
8939
|
+
app2.bind(createInvitationContract, [authenticate, requirePermissions("user:invite")], async (c) => {
|
|
8808
8940
|
const body = await c.data();
|
|
8809
8941
|
const { userId } = getAuth(c);
|
|
8810
8942
|
const invitation = await createInvitation({
|
|
@@ -8825,7 +8957,7 @@ var init_invitations2 = __esm({
|
|
|
8825
8957
|
invitationUrl
|
|
8826
8958
|
});
|
|
8827
8959
|
});
|
|
8828
|
-
app2.bind(listInvitationsContract, [authenticate], async (c) => {
|
|
8960
|
+
app2.bind(listInvitationsContract, [authenticate, requirePermissions("user:read")], async (c) => {
|
|
8829
8961
|
const query = await c.data();
|
|
8830
8962
|
const result = await listInvitations({
|
|
8831
8963
|
status: query.status,
|
|
@@ -8844,7 +8976,7 @@ var init_invitations2 = __esm({
|
|
|
8844
8976
|
invitations: formattedInvitations
|
|
8845
8977
|
});
|
|
8846
8978
|
});
|
|
8847
|
-
app2.bind(cancelInvitationContract, [authenticate], async (c) => {
|
|
8979
|
+
app2.bind(cancelInvitationContract, [authenticate, requirePermissions("user:invite")], async (c) => {
|
|
8848
8980
|
const data = await c.data();
|
|
8849
8981
|
const { userId } = getAuth(c);
|
|
8850
8982
|
await cancelInvitation(
|
|
@@ -8857,7 +8989,7 @@ var init_invitations2 = __esm({
|
|
|
8857
8989
|
cancelledAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
8858
8990
|
});
|
|
8859
8991
|
});
|
|
8860
|
-
app2.bind(resendInvitationContract, [authenticate], async (c) => {
|
|
8992
|
+
app2.bind(resendInvitationContract, [authenticate, requirePermissions("user:invite")], async (c) => {
|
|
8861
8993
|
const data = await c.data();
|
|
8862
8994
|
const updated = await resendInvitation(
|
|
8863
8995
|
data.id,
|
|
@@ -8868,7 +9000,7 @@ var init_invitations2 = __esm({
|
|
|
8868
9000
|
expiresAt: updated.expiresAt.toISOString()
|
|
8869
9001
|
});
|
|
8870
9002
|
});
|
|
8871
|
-
app2.bind(deleteInvitationContract, [authenticate], async (c) => {
|
|
9003
|
+
app2.bind(deleteInvitationContract, [authenticate, requireRole("superadmin")], async (c) => {
|
|
8872
9004
|
const data = await c.data();
|
|
8873
9005
|
await deleteInvitation(data.id);
|
|
8874
9006
|
return c.success({
|
|
@@ -8900,8 +9032,8 @@ var init_routes = __esm({
|
|
|
8900
9032
|
|
|
8901
9033
|
// src/plugin.ts
|
|
8902
9034
|
init_rbac_service();
|
|
8903
|
-
import { logger } from "@spfn/core/logger";
|
|
8904
|
-
var
|
|
9035
|
+
import { logger as logger2 } from "@spfn/core/logger";
|
|
9036
|
+
var authLogger2 = logger2.child("auth-plugin");
|
|
8905
9037
|
var spfnPlugin = {
|
|
8906
9038
|
name: "@spfn/auth",
|
|
8907
9039
|
/**
|
|
@@ -8909,12 +9041,12 @@ var spfnPlugin = {
|
|
|
8909
9041
|
* Creates default roles (user, admin, superadmin) and permissions
|
|
8910
9042
|
*/
|
|
8911
9043
|
afterInfrastructure: async () => {
|
|
8912
|
-
|
|
9044
|
+
authLogger2.info("Initializing authentication system...");
|
|
8913
9045
|
try {
|
|
8914
9046
|
await initializeAuth();
|
|
8915
|
-
|
|
9047
|
+
authLogger2.info("Authentication system initialized successfully");
|
|
8916
9048
|
} catch (error) {
|
|
8917
|
-
|
|
9049
|
+
authLogger2.error("Failed to initialize authentication system", error);
|
|
8918
9050
|
throw error;
|
|
8919
9051
|
}
|
|
8920
9052
|
},
|
|
@@ -8923,13 +9055,13 @@ var spfnPlugin = {
|
|
|
8923
9055
|
* Routes are auto-discovered from src/server/routes
|
|
8924
9056
|
*/
|
|
8925
9057
|
beforeRoutes: async (app4) => {
|
|
8926
|
-
|
|
9058
|
+
authLogger2.info("Mounting authentication routes...");
|
|
8927
9059
|
try {
|
|
8928
9060
|
const authRoutes = await Promise.resolve().then(() => (init_routes(), routes_exports));
|
|
8929
9061
|
app4.route("/_auth", authRoutes.default);
|
|
8930
|
-
|
|
9062
|
+
authLogger2.info("Authentication routes mounted at /_auth");
|
|
8931
9063
|
} catch (error) {
|
|
8932
|
-
|
|
9064
|
+
authLogger2.error("Failed to mount authentication routes", error);
|
|
8933
9065
|
throw error;
|
|
8934
9066
|
}
|
|
8935
9067
|
},
|
|
@@ -8937,7 +9069,7 @@ var spfnPlugin = {
|
|
|
8937
9069
|
* Log successful startup
|
|
8938
9070
|
*/
|
|
8939
9071
|
afterStart: async () => {
|
|
8940
|
-
|
|
9072
|
+
authLogger2.info("@spfn/auth plugin started successfully", {
|
|
8941
9073
|
routes: "/_auth/*",
|
|
8942
9074
|
rbac: "enabled"
|
|
8943
9075
|
});
|