@objectstack/plugin-auth 3.2.5 → 3.2.7
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/.turbo/turbo-build.log +66 -10
- package/CHANGELOG.md +15 -0
- package/dist/index.d.mts +9998 -51
- package/dist/index.d.ts +9998 -51
- package/dist/index.js +551 -40
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +540 -40
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -4
- package/src/auth-manager.test.ts +345 -0
- package/src/auth-manager.ts +71 -2
- package/src/auth-plugin.test.ts +89 -0
- package/src/auth-plugin.ts +21 -0
- package/src/auth-schema-config.ts +6 -6
- package/src/objects/auth-account.object.ts +3 -117
- package/src/objects/auth-session.object.ts +3 -85
- package/src/objects/auth-user.object.ts +3 -93
- package/src/objects/auth-verification.object.ts +3 -74
- package/src/objects/index.ts +30 -4
- package/src/objects/sys-account.object.ts +111 -0
- package/src/objects/sys-api-key.object.ts +104 -0
- package/src/objects/sys-invitation.object.ts +93 -0
- package/src/objects/sys-member.object.ts +68 -0
- package/src/objects/sys-organization.object.ts +82 -0
- package/src/objects/sys-session.object.ts +84 -0
- package/src/objects/sys-team-member.object.ts +61 -0
- package/src/objects/sys-team.object.ts +69 -0
- package/src/objects/sys-two-factor.object.ts +73 -0
- package/src/objects/sys-user.object.ts +91 -0
- package/src/objects/sys-verification.object.ts +75 -0
package/dist/index.mjs
CHANGED
|
@@ -216,14 +216,16 @@ var AUTH_VERIFICATION_CONFIG = {
|
|
|
216
216
|
}
|
|
217
217
|
};
|
|
218
218
|
var AUTH_ORGANIZATION_SCHEMA = {
|
|
219
|
-
modelName:
|
|
219
|
+
modelName: SystemObjectName2.ORGANIZATION,
|
|
220
|
+
// 'sys_organization'
|
|
220
221
|
fields: {
|
|
221
222
|
createdAt: "created_at",
|
|
222
223
|
updatedAt: "updated_at"
|
|
223
224
|
}
|
|
224
225
|
};
|
|
225
226
|
var AUTH_MEMBER_SCHEMA = {
|
|
226
|
-
modelName:
|
|
227
|
+
modelName: SystemObjectName2.MEMBER,
|
|
228
|
+
// 'sys_member'
|
|
227
229
|
fields: {
|
|
228
230
|
organizationId: "organization_id",
|
|
229
231
|
userId: "user_id",
|
|
@@ -231,7 +233,8 @@ var AUTH_MEMBER_SCHEMA = {
|
|
|
231
233
|
}
|
|
232
234
|
};
|
|
233
235
|
var AUTH_INVITATION_SCHEMA = {
|
|
234
|
-
modelName:
|
|
236
|
+
modelName: SystemObjectName2.INVITATION,
|
|
237
|
+
// 'sys_invitation'
|
|
235
238
|
fields: {
|
|
236
239
|
organizationId: "organization_id",
|
|
237
240
|
inviterId: "inviter_id",
|
|
@@ -245,7 +248,8 @@ var AUTH_ORG_SESSION_FIELDS = {
|
|
|
245
248
|
activeTeamId: "active_team_id"
|
|
246
249
|
};
|
|
247
250
|
var AUTH_TEAM_SCHEMA = {
|
|
248
|
-
modelName:
|
|
251
|
+
modelName: SystemObjectName2.TEAM,
|
|
252
|
+
// 'sys_team'
|
|
249
253
|
fields: {
|
|
250
254
|
organizationId: "organization_id",
|
|
251
255
|
createdAt: "created_at",
|
|
@@ -253,7 +257,8 @@ var AUTH_TEAM_SCHEMA = {
|
|
|
253
257
|
}
|
|
254
258
|
};
|
|
255
259
|
var AUTH_TEAM_MEMBER_SCHEMA = {
|
|
256
|
-
modelName:
|
|
260
|
+
modelName: SystemObjectName2.TEAM_MEMBER,
|
|
261
|
+
// 'sys_team_member'
|
|
257
262
|
fields: {
|
|
258
263
|
teamId: "team_id",
|
|
259
264
|
userId: "user_id",
|
|
@@ -261,7 +266,8 @@ var AUTH_TEAM_MEMBER_SCHEMA = {
|
|
|
261
266
|
}
|
|
262
267
|
};
|
|
263
268
|
var AUTH_TWO_FACTOR_SCHEMA = {
|
|
264
|
-
modelName:
|
|
269
|
+
modelName: SystemObjectName2.TWO_FACTOR,
|
|
270
|
+
// 'sys_two_factor'
|
|
265
271
|
fields: {
|
|
266
272
|
backupCodes: "backup_codes",
|
|
267
273
|
userId: "user_id"
|
|
@@ -333,10 +339,28 @@ var AuthManager = class {
|
|
|
333
339
|
verification: {
|
|
334
340
|
...AUTH_VERIFICATION_CONFIG
|
|
335
341
|
},
|
|
336
|
-
//
|
|
342
|
+
// Social / OAuth providers
|
|
343
|
+
...this.config.socialProviders ? { socialProviders: this.config.socialProviders } : {},
|
|
344
|
+
// Email and password configuration
|
|
337
345
|
emailAndPassword: {
|
|
338
|
-
enabled: true
|
|
346
|
+
enabled: this.config.emailAndPassword?.enabled ?? true,
|
|
347
|
+
...this.config.emailAndPassword?.disableSignUp != null ? { disableSignUp: this.config.emailAndPassword.disableSignUp } : {},
|
|
348
|
+
...this.config.emailAndPassword?.requireEmailVerification != null ? { requireEmailVerification: this.config.emailAndPassword.requireEmailVerification } : {},
|
|
349
|
+
...this.config.emailAndPassword?.minPasswordLength != null ? { minPasswordLength: this.config.emailAndPassword.minPasswordLength } : {},
|
|
350
|
+
...this.config.emailAndPassword?.maxPasswordLength != null ? { maxPasswordLength: this.config.emailAndPassword.maxPasswordLength } : {},
|
|
351
|
+
...this.config.emailAndPassword?.resetPasswordTokenExpiresIn != null ? { resetPasswordTokenExpiresIn: this.config.emailAndPassword.resetPasswordTokenExpiresIn } : {},
|
|
352
|
+
...this.config.emailAndPassword?.autoSignIn != null ? { autoSignIn: this.config.emailAndPassword.autoSignIn } : {},
|
|
353
|
+
...this.config.emailAndPassword?.revokeSessionsOnPasswordReset != null ? { revokeSessionsOnPasswordReset: this.config.emailAndPassword.revokeSessionsOnPasswordReset } : {}
|
|
339
354
|
},
|
|
355
|
+
// Email verification
|
|
356
|
+
...this.config.emailVerification ? {
|
|
357
|
+
emailVerification: {
|
|
358
|
+
...this.config.emailVerification.sendOnSignUp != null ? { sendOnSignUp: this.config.emailVerification.sendOnSignUp } : {},
|
|
359
|
+
...this.config.emailVerification.sendOnSignIn != null ? { sendOnSignIn: this.config.emailVerification.sendOnSignIn } : {},
|
|
360
|
+
...this.config.emailVerification.autoSignInAfterVerification != null ? { autoSignInAfterVerification: this.config.emailVerification.autoSignInAfterVerification } : {},
|
|
361
|
+
...this.config.emailVerification.expiresIn != null ? { expiresIn: this.config.emailVerification.expiresIn } : {}
|
|
362
|
+
}
|
|
363
|
+
} : {},
|
|
340
364
|
// Session configuration
|
|
341
365
|
session: {
|
|
342
366
|
...AUTH_SESSION_CONFIG,
|
|
@@ -346,7 +370,18 @@ var AuthManager = class {
|
|
|
346
370
|
// 1 day default
|
|
347
371
|
},
|
|
348
372
|
// better-auth plugins — registered based on AuthPluginConfig flags
|
|
349
|
-
plugins: this.buildPluginList()
|
|
373
|
+
plugins: this.buildPluginList(),
|
|
374
|
+
// Trusted origins for CSRF protection (supports wildcards like "https://*.example.com")
|
|
375
|
+
...this.config.trustedOrigins?.length ? { trustedOrigins: this.config.trustedOrigins } : {},
|
|
376
|
+
// Advanced options (cross-subdomain cookies, secure cookies, CSRF, etc.)
|
|
377
|
+
...this.config.advanced ? {
|
|
378
|
+
advanced: {
|
|
379
|
+
...this.config.advanced.crossSubDomainCookies ? { crossSubDomainCookies: this.config.advanced.crossSubDomainCookies } : {},
|
|
380
|
+
...this.config.advanced.useSecureCookies != null ? { useSecureCookies: this.config.advanced.useSecureCookies } : {},
|
|
381
|
+
...this.config.advanced.disableCSRFCheck != null ? { disableCSRFCheck: this.config.advanced.disableCSRFCheck } : {},
|
|
382
|
+
...this.config.advanced.cookiePrefix != null ? { cookiePrefix: this.config.advanced.cookiePrefix } : {}
|
|
383
|
+
}
|
|
384
|
+
} : {}
|
|
350
385
|
};
|
|
351
386
|
return betterAuth(betterAuthConfig);
|
|
352
387
|
}
|
|
@@ -416,6 +451,25 @@ var AuthManager = class {
|
|
|
416
451
|
}
|
|
417
452
|
return envSecret;
|
|
418
453
|
}
|
|
454
|
+
/**
|
|
455
|
+
* Update the base URL at runtime.
|
|
456
|
+
*
|
|
457
|
+
* This **must** be called before the first request triggers lazy
|
|
458
|
+
* initialisation of the better-auth instance — typically from a
|
|
459
|
+
* `kernel:ready` hook where the actual server port is known.
|
|
460
|
+
*
|
|
461
|
+
* If the auth instance has already been created this is a no-op and
|
|
462
|
+
* a warning is emitted.
|
|
463
|
+
*/
|
|
464
|
+
setRuntimeBaseUrl(url) {
|
|
465
|
+
if (this.auth) {
|
|
466
|
+
console.warn(
|
|
467
|
+
"[AuthManager] setRuntimeBaseUrl() called after the auth instance was already created \u2014 ignoring. Ensure this method is called before the first request."
|
|
468
|
+
);
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
this.config = { ...this.config, baseUrl: url };
|
|
472
|
+
}
|
|
419
473
|
/**
|
|
420
474
|
* Get the underlying better-auth instance
|
|
421
475
|
* Useful for advanced use cases
|
|
@@ -499,6 +553,21 @@ var AuthPlugin = class {
|
|
|
499
553
|
} catch {
|
|
500
554
|
}
|
|
501
555
|
if (httpServer) {
|
|
556
|
+
const serverWithPort = httpServer;
|
|
557
|
+
if (this.authManager && typeof serverWithPort.getPort === "function") {
|
|
558
|
+
const actualPort = serverWithPort.getPort();
|
|
559
|
+
if (actualPort) {
|
|
560
|
+
const configuredUrl = this.options.baseUrl || "http://localhost:3000";
|
|
561
|
+
const configuredOrigin = new URL(configuredUrl).origin;
|
|
562
|
+
const actualUrl = `http://localhost:${actualPort}`;
|
|
563
|
+
if (configuredOrigin !== actualUrl) {
|
|
564
|
+
this.authManager.setRuntimeBaseUrl(actualUrl);
|
|
565
|
+
ctx.logger.info(
|
|
566
|
+
`Auth baseUrl auto-updated to ${actualUrl} (configured: ${configuredUrl})`
|
|
567
|
+
);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
}
|
|
502
571
|
this.registerAuthRoutes(httpServer, ctx);
|
|
503
572
|
ctx.logger.info(`Auth routes registered at ${this.options.basePath}`);
|
|
504
573
|
} else {
|
|
@@ -580,18 +649,19 @@ var AuthPlugin = class {
|
|
|
580
649
|
}
|
|
581
650
|
};
|
|
582
651
|
|
|
583
|
-
// src/objects/
|
|
652
|
+
// src/objects/sys-user.object.ts
|
|
584
653
|
import { ObjectSchema, Field } from "@objectstack/spec/data";
|
|
585
|
-
var
|
|
586
|
-
|
|
654
|
+
var SysUser = ObjectSchema.create({
|
|
655
|
+
namespace: "sys",
|
|
656
|
+
name: "user",
|
|
587
657
|
label: "User",
|
|
588
658
|
pluralLabel: "Users",
|
|
589
659
|
icon: "user",
|
|
660
|
+
isSystem: true,
|
|
590
661
|
description: "User accounts for authentication",
|
|
591
662
|
titleFormat: "{name} ({email})",
|
|
592
663
|
compactLayout: ["name", "email", "email_verified"],
|
|
593
664
|
fields: {
|
|
594
|
-
// ID is auto-generated by ObjectQL
|
|
595
665
|
id: Field.text({
|
|
596
666
|
label: "User ID",
|
|
597
667
|
required: true,
|
|
@@ -627,12 +697,10 @@ var AuthUser = ObjectSchema.create({
|
|
|
627
697
|
required: false
|
|
628
698
|
})
|
|
629
699
|
},
|
|
630
|
-
// Database indexes for performance
|
|
631
700
|
indexes: [
|
|
632
701
|
{ fields: ["email"], unique: true },
|
|
633
702
|
{ fields: ["created_at"], unique: false }
|
|
634
703
|
],
|
|
635
|
-
// Enable features
|
|
636
704
|
enable: {
|
|
637
705
|
trackHistory: true,
|
|
638
706
|
searchable: true,
|
|
@@ -641,7 +709,6 @@ var AuthUser = ObjectSchema.create({
|
|
|
641
709
|
trash: true,
|
|
642
710
|
mru: true
|
|
643
711
|
},
|
|
644
|
-
// Validation Rules
|
|
645
712
|
validations: [
|
|
646
713
|
{
|
|
647
714
|
name: "email_unique",
|
|
@@ -654,13 +721,15 @@ var AuthUser = ObjectSchema.create({
|
|
|
654
721
|
]
|
|
655
722
|
});
|
|
656
723
|
|
|
657
|
-
// src/objects/
|
|
724
|
+
// src/objects/sys-session.object.ts
|
|
658
725
|
import { ObjectSchema as ObjectSchema2, Field as Field2 } from "@objectstack/spec/data";
|
|
659
|
-
var
|
|
660
|
-
|
|
726
|
+
var SysSession = ObjectSchema2.create({
|
|
727
|
+
namespace: "sys",
|
|
728
|
+
name: "session",
|
|
661
729
|
label: "Session",
|
|
662
730
|
pluralLabel: "Sessions",
|
|
663
731
|
icon: "key",
|
|
732
|
+
isSystem: true,
|
|
664
733
|
description: "Active user sessions",
|
|
665
734
|
titleFormat: "Session {token}",
|
|
666
735
|
compactLayout: ["user_id", "expires_at", "ip_address"],
|
|
@@ -703,33 +772,30 @@ var AuthSession = ObjectSchema2.create({
|
|
|
703
772
|
required: false
|
|
704
773
|
})
|
|
705
774
|
},
|
|
706
|
-
// Database indexes for performance
|
|
707
775
|
indexes: [
|
|
708
776
|
{ fields: ["token"], unique: true },
|
|
709
777
|
{ fields: ["user_id"], unique: false },
|
|
710
778
|
{ fields: ["expires_at"], unique: false }
|
|
711
779
|
],
|
|
712
|
-
// Enable features
|
|
713
780
|
enable: {
|
|
714
781
|
trackHistory: false,
|
|
715
|
-
// Sessions don't need history tracking
|
|
716
782
|
searchable: false,
|
|
717
783
|
apiEnabled: true,
|
|
718
784
|
apiMethods: ["get", "list", "create", "delete"],
|
|
719
|
-
// No update for sessions
|
|
720
785
|
trash: false,
|
|
721
|
-
// Sessions should be hard deleted
|
|
722
786
|
mru: false
|
|
723
787
|
}
|
|
724
788
|
});
|
|
725
789
|
|
|
726
|
-
// src/objects/
|
|
790
|
+
// src/objects/sys-account.object.ts
|
|
727
791
|
import { ObjectSchema as ObjectSchema3, Field as Field3 } from "@objectstack/spec/data";
|
|
728
|
-
var
|
|
729
|
-
|
|
792
|
+
var SysAccount = ObjectSchema3.create({
|
|
793
|
+
namespace: "sys",
|
|
794
|
+
name: "account",
|
|
730
795
|
label: "Account",
|
|
731
796
|
pluralLabel: "Accounts",
|
|
732
797
|
icon: "link",
|
|
798
|
+
isSystem: true,
|
|
733
799
|
description: "OAuth and authentication provider accounts",
|
|
734
800
|
titleFormat: "{provider_id} - {account_id}",
|
|
735
801
|
compactLayout: ["provider_id", "user_id", "account_id"],
|
|
@@ -794,12 +860,10 @@ var AuthAccount = ObjectSchema3.create({
|
|
|
794
860
|
description: "Hashed password for email/password provider"
|
|
795
861
|
})
|
|
796
862
|
},
|
|
797
|
-
// Database indexes for performance
|
|
798
863
|
indexes: [
|
|
799
864
|
{ fields: ["user_id"], unique: false },
|
|
800
865
|
{ fields: ["provider_id", "account_id"], unique: true }
|
|
801
866
|
],
|
|
802
|
-
// Enable features
|
|
803
867
|
enable: {
|
|
804
868
|
trackHistory: false,
|
|
805
869
|
searchable: false,
|
|
@@ -810,13 +874,15 @@ var AuthAccount = ObjectSchema3.create({
|
|
|
810
874
|
}
|
|
811
875
|
});
|
|
812
876
|
|
|
813
|
-
// src/objects/
|
|
877
|
+
// src/objects/sys-verification.object.ts
|
|
814
878
|
import { ObjectSchema as ObjectSchema4, Field as Field4 } from "@objectstack/spec/data";
|
|
815
|
-
var
|
|
816
|
-
|
|
879
|
+
var SysVerification = ObjectSchema4.create({
|
|
880
|
+
namespace: "sys",
|
|
881
|
+
name: "verification",
|
|
817
882
|
label: "Verification",
|
|
818
883
|
pluralLabel: "Verifications",
|
|
819
884
|
icon: "shield-check",
|
|
885
|
+
isSystem: true,
|
|
820
886
|
description: "Email and phone verification tokens",
|
|
821
887
|
titleFormat: "Verification for {identifier}",
|
|
822
888
|
compactLayout: ["identifier", "expires_at", "created_at"],
|
|
@@ -851,21 +917,444 @@ var AuthVerification = ObjectSchema4.create({
|
|
|
851
917
|
description: "Email address or phone number"
|
|
852
918
|
})
|
|
853
919
|
},
|
|
854
|
-
// Database indexes for performance
|
|
855
920
|
indexes: [
|
|
856
921
|
{ fields: ["value"], unique: true },
|
|
857
922
|
{ fields: ["identifier"], unique: false },
|
|
858
923
|
{ fields: ["expires_at"], unique: false }
|
|
859
924
|
],
|
|
860
|
-
// Enable features
|
|
861
925
|
enable: {
|
|
862
926
|
trackHistory: false,
|
|
863
927
|
searchable: false,
|
|
864
928
|
apiEnabled: true,
|
|
865
929
|
apiMethods: ["get", "create", "delete"],
|
|
866
|
-
// No list or update
|
|
867
930
|
trash: false,
|
|
868
|
-
|
|
931
|
+
mru: false
|
|
932
|
+
}
|
|
933
|
+
});
|
|
934
|
+
|
|
935
|
+
// src/objects/sys-organization.object.ts
|
|
936
|
+
import { ObjectSchema as ObjectSchema5, Field as Field5 } from "@objectstack/spec/data";
|
|
937
|
+
var SysOrganization = ObjectSchema5.create({
|
|
938
|
+
namespace: "sys",
|
|
939
|
+
name: "organization",
|
|
940
|
+
label: "Organization",
|
|
941
|
+
pluralLabel: "Organizations",
|
|
942
|
+
icon: "building-2",
|
|
943
|
+
isSystem: true,
|
|
944
|
+
description: "Organizations for multi-tenant grouping",
|
|
945
|
+
titleFormat: "{name}",
|
|
946
|
+
compactLayout: ["name", "slug", "created_at"],
|
|
947
|
+
fields: {
|
|
948
|
+
id: Field5.text({
|
|
949
|
+
label: "Organization ID",
|
|
950
|
+
required: true,
|
|
951
|
+
readonly: true
|
|
952
|
+
}),
|
|
953
|
+
created_at: Field5.datetime({
|
|
954
|
+
label: "Created At",
|
|
955
|
+
defaultValue: "NOW()",
|
|
956
|
+
readonly: true
|
|
957
|
+
}),
|
|
958
|
+
updated_at: Field5.datetime({
|
|
959
|
+
label: "Updated At",
|
|
960
|
+
defaultValue: "NOW()",
|
|
961
|
+
readonly: true
|
|
962
|
+
}),
|
|
963
|
+
name: Field5.text({
|
|
964
|
+
label: "Name",
|
|
965
|
+
required: true,
|
|
966
|
+
searchable: true,
|
|
967
|
+
maxLength: 255
|
|
968
|
+
}),
|
|
969
|
+
slug: Field5.text({
|
|
970
|
+
label: "Slug",
|
|
971
|
+
required: false,
|
|
972
|
+
maxLength: 255,
|
|
973
|
+
description: "URL-friendly identifier"
|
|
974
|
+
}),
|
|
975
|
+
logo: Field5.url({
|
|
976
|
+
label: "Logo",
|
|
977
|
+
required: false
|
|
978
|
+
}),
|
|
979
|
+
metadata: Field5.textarea({
|
|
980
|
+
label: "Metadata",
|
|
981
|
+
required: false,
|
|
982
|
+
description: "JSON-serialized organization metadata"
|
|
983
|
+
})
|
|
984
|
+
},
|
|
985
|
+
indexes: [
|
|
986
|
+
{ fields: ["slug"], unique: true },
|
|
987
|
+
{ fields: ["name"] }
|
|
988
|
+
],
|
|
989
|
+
enable: {
|
|
990
|
+
trackHistory: true,
|
|
991
|
+
searchable: true,
|
|
992
|
+
apiEnabled: true,
|
|
993
|
+
apiMethods: ["get", "list", "create", "update", "delete"],
|
|
994
|
+
trash: true,
|
|
995
|
+
mru: true
|
|
996
|
+
}
|
|
997
|
+
});
|
|
998
|
+
|
|
999
|
+
// src/objects/sys-member.object.ts
|
|
1000
|
+
import { ObjectSchema as ObjectSchema6, Field as Field6 } from "@objectstack/spec/data";
|
|
1001
|
+
var SysMember = ObjectSchema6.create({
|
|
1002
|
+
namespace: "sys",
|
|
1003
|
+
name: "member",
|
|
1004
|
+
label: "Member",
|
|
1005
|
+
pluralLabel: "Members",
|
|
1006
|
+
icon: "user-check",
|
|
1007
|
+
isSystem: true,
|
|
1008
|
+
description: "Organization membership records",
|
|
1009
|
+
titleFormat: "{user_id} in {organization_id}",
|
|
1010
|
+
compactLayout: ["user_id", "organization_id", "role"],
|
|
1011
|
+
fields: {
|
|
1012
|
+
id: Field6.text({
|
|
1013
|
+
label: "Member ID",
|
|
1014
|
+
required: true,
|
|
1015
|
+
readonly: true
|
|
1016
|
+
}),
|
|
1017
|
+
created_at: Field6.datetime({
|
|
1018
|
+
label: "Created At",
|
|
1019
|
+
defaultValue: "NOW()",
|
|
1020
|
+
readonly: true
|
|
1021
|
+
}),
|
|
1022
|
+
organization_id: Field6.text({
|
|
1023
|
+
label: "Organization ID",
|
|
1024
|
+
required: true
|
|
1025
|
+
}),
|
|
1026
|
+
user_id: Field6.text({
|
|
1027
|
+
label: "User ID",
|
|
1028
|
+
required: true
|
|
1029
|
+
}),
|
|
1030
|
+
role: Field6.text({
|
|
1031
|
+
label: "Role",
|
|
1032
|
+
required: false,
|
|
1033
|
+
description: "Member role within the organization (e.g. admin, member)",
|
|
1034
|
+
maxLength: 100
|
|
1035
|
+
})
|
|
1036
|
+
},
|
|
1037
|
+
indexes: [
|
|
1038
|
+
{ fields: ["organization_id", "user_id"], unique: true },
|
|
1039
|
+
{ fields: ["user_id"] }
|
|
1040
|
+
],
|
|
1041
|
+
enable: {
|
|
1042
|
+
trackHistory: true,
|
|
1043
|
+
searchable: false,
|
|
1044
|
+
apiEnabled: true,
|
|
1045
|
+
apiMethods: ["get", "list", "create", "update", "delete"],
|
|
1046
|
+
trash: false,
|
|
1047
|
+
mru: false
|
|
1048
|
+
}
|
|
1049
|
+
});
|
|
1050
|
+
|
|
1051
|
+
// src/objects/sys-invitation.object.ts
|
|
1052
|
+
import { ObjectSchema as ObjectSchema7, Field as Field7 } from "@objectstack/spec/data";
|
|
1053
|
+
var SysInvitation = ObjectSchema7.create({
|
|
1054
|
+
namespace: "sys",
|
|
1055
|
+
name: "invitation",
|
|
1056
|
+
label: "Invitation",
|
|
1057
|
+
pluralLabel: "Invitations",
|
|
1058
|
+
icon: "mail",
|
|
1059
|
+
isSystem: true,
|
|
1060
|
+
description: "Organization invitations for user onboarding",
|
|
1061
|
+
titleFormat: "Invitation to {organization_id}",
|
|
1062
|
+
compactLayout: ["email", "organization_id", "status"],
|
|
1063
|
+
fields: {
|
|
1064
|
+
id: Field7.text({
|
|
1065
|
+
label: "Invitation ID",
|
|
1066
|
+
required: true,
|
|
1067
|
+
readonly: true
|
|
1068
|
+
}),
|
|
1069
|
+
created_at: Field7.datetime({
|
|
1070
|
+
label: "Created At",
|
|
1071
|
+
defaultValue: "NOW()",
|
|
1072
|
+
readonly: true
|
|
1073
|
+
}),
|
|
1074
|
+
organization_id: Field7.text({
|
|
1075
|
+
label: "Organization ID",
|
|
1076
|
+
required: true
|
|
1077
|
+
}),
|
|
1078
|
+
email: Field7.email({
|
|
1079
|
+
label: "Email",
|
|
1080
|
+
required: true,
|
|
1081
|
+
description: "Email address of the invited user"
|
|
1082
|
+
}),
|
|
1083
|
+
role: Field7.text({
|
|
1084
|
+
label: "Role",
|
|
1085
|
+
required: false,
|
|
1086
|
+
maxLength: 100,
|
|
1087
|
+
description: "Role to assign upon acceptance"
|
|
1088
|
+
}),
|
|
1089
|
+
status: Field7.select(["pending", "accepted", "rejected", "expired", "canceled"], {
|
|
1090
|
+
label: "Status",
|
|
1091
|
+
required: true,
|
|
1092
|
+
defaultValue: "pending"
|
|
1093
|
+
}),
|
|
1094
|
+
inviter_id: Field7.text({
|
|
1095
|
+
label: "Inviter ID",
|
|
1096
|
+
required: true,
|
|
1097
|
+
description: "User ID of the person who sent the invitation"
|
|
1098
|
+
}),
|
|
1099
|
+
expires_at: Field7.datetime({
|
|
1100
|
+
label: "Expires At",
|
|
1101
|
+
required: true
|
|
1102
|
+
}),
|
|
1103
|
+
team_id: Field7.text({
|
|
1104
|
+
label: "Team ID",
|
|
1105
|
+
required: false,
|
|
1106
|
+
description: "Optional team to assign upon acceptance"
|
|
1107
|
+
})
|
|
1108
|
+
},
|
|
1109
|
+
indexes: [
|
|
1110
|
+
{ fields: ["organization_id"] },
|
|
1111
|
+
{ fields: ["email"] },
|
|
1112
|
+
{ fields: ["expires_at"] }
|
|
1113
|
+
],
|
|
1114
|
+
enable: {
|
|
1115
|
+
trackHistory: true,
|
|
1116
|
+
searchable: false,
|
|
1117
|
+
apiEnabled: true,
|
|
1118
|
+
apiMethods: ["get", "list", "create", "update", "delete"],
|
|
1119
|
+
trash: false,
|
|
1120
|
+
mru: false
|
|
1121
|
+
}
|
|
1122
|
+
});
|
|
1123
|
+
|
|
1124
|
+
// src/objects/sys-team.object.ts
|
|
1125
|
+
import { ObjectSchema as ObjectSchema8, Field as Field8 } from "@objectstack/spec/data";
|
|
1126
|
+
var SysTeam = ObjectSchema8.create({
|
|
1127
|
+
namespace: "sys",
|
|
1128
|
+
name: "team",
|
|
1129
|
+
label: "Team",
|
|
1130
|
+
pluralLabel: "Teams",
|
|
1131
|
+
icon: "users",
|
|
1132
|
+
isSystem: true,
|
|
1133
|
+
description: "Teams within organizations for fine-grained grouping",
|
|
1134
|
+
titleFormat: "{name}",
|
|
1135
|
+
compactLayout: ["name", "organization_id", "created_at"],
|
|
1136
|
+
fields: {
|
|
1137
|
+
id: Field8.text({
|
|
1138
|
+
label: "Team ID",
|
|
1139
|
+
required: true,
|
|
1140
|
+
readonly: true
|
|
1141
|
+
}),
|
|
1142
|
+
created_at: Field8.datetime({
|
|
1143
|
+
label: "Created At",
|
|
1144
|
+
defaultValue: "NOW()",
|
|
1145
|
+
readonly: true
|
|
1146
|
+
}),
|
|
1147
|
+
updated_at: Field8.datetime({
|
|
1148
|
+
label: "Updated At",
|
|
1149
|
+
defaultValue: "NOW()",
|
|
1150
|
+
readonly: true
|
|
1151
|
+
}),
|
|
1152
|
+
name: Field8.text({
|
|
1153
|
+
label: "Name",
|
|
1154
|
+
required: true,
|
|
1155
|
+
searchable: true,
|
|
1156
|
+
maxLength: 255
|
|
1157
|
+
}),
|
|
1158
|
+
organization_id: Field8.text({
|
|
1159
|
+
label: "Organization ID",
|
|
1160
|
+
required: true
|
|
1161
|
+
})
|
|
1162
|
+
},
|
|
1163
|
+
indexes: [
|
|
1164
|
+
{ fields: ["organization_id"] },
|
|
1165
|
+
{ fields: ["name", "organization_id"], unique: true }
|
|
1166
|
+
],
|
|
1167
|
+
enable: {
|
|
1168
|
+
trackHistory: true,
|
|
1169
|
+
searchable: true,
|
|
1170
|
+
apiEnabled: true,
|
|
1171
|
+
apiMethods: ["get", "list", "create", "update", "delete"],
|
|
1172
|
+
trash: true,
|
|
1173
|
+
mru: false
|
|
1174
|
+
}
|
|
1175
|
+
});
|
|
1176
|
+
|
|
1177
|
+
// src/objects/sys-team-member.object.ts
|
|
1178
|
+
import { ObjectSchema as ObjectSchema9, Field as Field9 } from "@objectstack/spec/data";
|
|
1179
|
+
var SysTeamMember = ObjectSchema9.create({
|
|
1180
|
+
namespace: "sys",
|
|
1181
|
+
name: "team_member",
|
|
1182
|
+
label: "Team Member",
|
|
1183
|
+
pluralLabel: "Team Members",
|
|
1184
|
+
icon: "user-plus",
|
|
1185
|
+
isSystem: true,
|
|
1186
|
+
description: "Team membership records linking users to teams",
|
|
1187
|
+
titleFormat: "{user_id} in {team_id}",
|
|
1188
|
+
compactLayout: ["user_id", "team_id", "created_at"],
|
|
1189
|
+
fields: {
|
|
1190
|
+
id: Field9.text({
|
|
1191
|
+
label: "Team Member ID",
|
|
1192
|
+
required: true,
|
|
1193
|
+
readonly: true
|
|
1194
|
+
}),
|
|
1195
|
+
created_at: Field9.datetime({
|
|
1196
|
+
label: "Created At",
|
|
1197
|
+
defaultValue: "NOW()",
|
|
1198
|
+
readonly: true
|
|
1199
|
+
}),
|
|
1200
|
+
team_id: Field9.text({
|
|
1201
|
+
label: "Team ID",
|
|
1202
|
+
required: true
|
|
1203
|
+
}),
|
|
1204
|
+
user_id: Field9.text({
|
|
1205
|
+
label: "User ID",
|
|
1206
|
+
required: true
|
|
1207
|
+
})
|
|
1208
|
+
},
|
|
1209
|
+
indexes: [
|
|
1210
|
+
{ fields: ["team_id", "user_id"], unique: true },
|
|
1211
|
+
{ fields: ["user_id"] }
|
|
1212
|
+
],
|
|
1213
|
+
enable: {
|
|
1214
|
+
trackHistory: true,
|
|
1215
|
+
searchable: false,
|
|
1216
|
+
apiEnabled: true,
|
|
1217
|
+
apiMethods: ["get", "list", "create", "delete"],
|
|
1218
|
+
trash: false,
|
|
1219
|
+
mru: false
|
|
1220
|
+
}
|
|
1221
|
+
});
|
|
1222
|
+
|
|
1223
|
+
// src/objects/sys-api-key.object.ts
|
|
1224
|
+
import { ObjectSchema as ObjectSchema10, Field as Field10 } from "@objectstack/spec/data";
|
|
1225
|
+
var SysApiKey = ObjectSchema10.create({
|
|
1226
|
+
namespace: "sys",
|
|
1227
|
+
name: "api_key",
|
|
1228
|
+
label: "API Key",
|
|
1229
|
+
pluralLabel: "API Keys",
|
|
1230
|
+
icon: "key-round",
|
|
1231
|
+
isSystem: true,
|
|
1232
|
+
description: "API keys for programmatic access",
|
|
1233
|
+
titleFormat: "{name}",
|
|
1234
|
+
compactLayout: ["name", "user_id", "expires_at"],
|
|
1235
|
+
fields: {
|
|
1236
|
+
id: Field10.text({
|
|
1237
|
+
label: "API Key ID",
|
|
1238
|
+
required: true,
|
|
1239
|
+
readonly: true
|
|
1240
|
+
}),
|
|
1241
|
+
created_at: Field10.datetime({
|
|
1242
|
+
label: "Created At",
|
|
1243
|
+
defaultValue: "NOW()",
|
|
1244
|
+
readonly: true
|
|
1245
|
+
}),
|
|
1246
|
+
updated_at: Field10.datetime({
|
|
1247
|
+
label: "Updated At",
|
|
1248
|
+
defaultValue: "NOW()",
|
|
1249
|
+
readonly: true
|
|
1250
|
+
}),
|
|
1251
|
+
name: Field10.text({
|
|
1252
|
+
label: "Name",
|
|
1253
|
+
required: true,
|
|
1254
|
+
maxLength: 255,
|
|
1255
|
+
description: "Human-readable label for the API key"
|
|
1256
|
+
}),
|
|
1257
|
+
key: Field10.text({
|
|
1258
|
+
label: "Key",
|
|
1259
|
+
required: true,
|
|
1260
|
+
description: "Hashed API key value"
|
|
1261
|
+
}),
|
|
1262
|
+
prefix: Field10.text({
|
|
1263
|
+
label: "Prefix",
|
|
1264
|
+
required: false,
|
|
1265
|
+
maxLength: 16,
|
|
1266
|
+
description: 'Visible prefix for identifying the key (e.g., "osk_")'
|
|
1267
|
+
}),
|
|
1268
|
+
user_id: Field10.text({
|
|
1269
|
+
label: "User ID",
|
|
1270
|
+
required: true,
|
|
1271
|
+
description: "Owner user of this API key"
|
|
1272
|
+
}),
|
|
1273
|
+
scopes: Field10.textarea({
|
|
1274
|
+
label: "Scopes",
|
|
1275
|
+
required: false,
|
|
1276
|
+
description: "JSON array of permission scopes"
|
|
1277
|
+
}),
|
|
1278
|
+
expires_at: Field10.datetime({
|
|
1279
|
+
label: "Expires At",
|
|
1280
|
+
required: false
|
|
1281
|
+
}),
|
|
1282
|
+
last_used_at: Field10.datetime({
|
|
1283
|
+
label: "Last Used At",
|
|
1284
|
+
required: false
|
|
1285
|
+
}),
|
|
1286
|
+
revoked: Field10.boolean({
|
|
1287
|
+
label: "Revoked",
|
|
1288
|
+
defaultValue: false
|
|
1289
|
+
})
|
|
1290
|
+
},
|
|
1291
|
+
indexes: [
|
|
1292
|
+
{ fields: ["key"], unique: true },
|
|
1293
|
+
{ fields: ["user_id"] },
|
|
1294
|
+
{ fields: ["prefix"] }
|
|
1295
|
+
],
|
|
1296
|
+
enable: {
|
|
1297
|
+
trackHistory: true,
|
|
1298
|
+
searchable: false,
|
|
1299
|
+
apiEnabled: true,
|
|
1300
|
+
apiMethods: ["get", "list", "create", "update", "delete"],
|
|
1301
|
+
trash: false,
|
|
1302
|
+
mru: false
|
|
1303
|
+
}
|
|
1304
|
+
});
|
|
1305
|
+
|
|
1306
|
+
// src/objects/sys-two-factor.object.ts
|
|
1307
|
+
import { ObjectSchema as ObjectSchema11, Field as Field11 } from "@objectstack/spec/data";
|
|
1308
|
+
var SysTwoFactor = ObjectSchema11.create({
|
|
1309
|
+
namespace: "sys",
|
|
1310
|
+
name: "two_factor",
|
|
1311
|
+
label: "Two Factor",
|
|
1312
|
+
pluralLabel: "Two Factor Credentials",
|
|
1313
|
+
icon: "smartphone",
|
|
1314
|
+
isSystem: true,
|
|
1315
|
+
description: "Two-factor authentication credentials",
|
|
1316
|
+
titleFormat: "Two-factor for {user_id}",
|
|
1317
|
+
compactLayout: ["user_id", "created_at"],
|
|
1318
|
+
fields: {
|
|
1319
|
+
id: Field11.text({
|
|
1320
|
+
label: "Two Factor ID",
|
|
1321
|
+
required: true,
|
|
1322
|
+
readonly: true
|
|
1323
|
+
}),
|
|
1324
|
+
created_at: Field11.datetime({
|
|
1325
|
+
label: "Created At",
|
|
1326
|
+
defaultValue: "NOW()",
|
|
1327
|
+
readonly: true
|
|
1328
|
+
}),
|
|
1329
|
+
updated_at: Field11.datetime({
|
|
1330
|
+
label: "Updated At",
|
|
1331
|
+
defaultValue: "NOW()",
|
|
1332
|
+
readonly: true
|
|
1333
|
+
}),
|
|
1334
|
+
user_id: Field11.text({
|
|
1335
|
+
label: "User ID",
|
|
1336
|
+
required: true
|
|
1337
|
+
}),
|
|
1338
|
+
secret: Field11.text({
|
|
1339
|
+
label: "Secret",
|
|
1340
|
+
required: true,
|
|
1341
|
+
description: "TOTP secret key"
|
|
1342
|
+
}),
|
|
1343
|
+
backup_codes: Field11.textarea({
|
|
1344
|
+
label: "Backup Codes",
|
|
1345
|
+
required: false,
|
|
1346
|
+
description: "JSON-serialized backup recovery codes"
|
|
1347
|
+
})
|
|
1348
|
+
},
|
|
1349
|
+
indexes: [
|
|
1350
|
+
{ fields: ["user_id"], unique: true }
|
|
1351
|
+
],
|
|
1352
|
+
enable: {
|
|
1353
|
+
trackHistory: false,
|
|
1354
|
+
searchable: false,
|
|
1355
|
+
apiEnabled: true,
|
|
1356
|
+
apiMethods: ["get", "create", "update", "delete"],
|
|
1357
|
+
trash: false,
|
|
869
1358
|
mru: false
|
|
870
1359
|
}
|
|
871
1360
|
});
|
|
@@ -883,12 +1372,23 @@ export {
|
|
|
883
1372
|
AUTH_TWO_FACTOR_USER_FIELDS,
|
|
884
1373
|
AUTH_USER_CONFIG,
|
|
885
1374
|
AUTH_VERIFICATION_CONFIG,
|
|
886
|
-
AuthAccount,
|
|
1375
|
+
SysAccount as AuthAccount,
|
|
887
1376
|
AuthManager,
|
|
888
1377
|
AuthPlugin,
|
|
889
|
-
AuthSession,
|
|
890
|
-
AuthUser,
|
|
891
|
-
AuthVerification,
|
|
1378
|
+
SysSession as AuthSession,
|
|
1379
|
+
SysUser as AuthUser,
|
|
1380
|
+
SysVerification as AuthVerification,
|
|
1381
|
+
SysAccount,
|
|
1382
|
+
SysApiKey,
|
|
1383
|
+
SysInvitation,
|
|
1384
|
+
SysMember,
|
|
1385
|
+
SysOrganization,
|
|
1386
|
+
SysSession,
|
|
1387
|
+
SysTeam,
|
|
1388
|
+
SysTeamMember,
|
|
1389
|
+
SysTwoFactor,
|
|
1390
|
+
SysUser,
|
|
1391
|
+
SysVerification,
|
|
892
1392
|
buildOrganizationPluginSchema,
|
|
893
1393
|
buildTwoFactorPluginSchema,
|
|
894
1394
|
createObjectQLAdapter,
|