@objectstack/plugin-auth 3.2.4 → 3.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +65 -9
- package/CHANGELOG.md +15 -0
- package/dist/index.d.mts +9994 -51
- package/dist/index.d.ts +9994 -51
- package/dist/index.js +487 -52
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +476 -52
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -4
- package/src/auth-manager.test.ts +39 -0
- package/src/auth-manager.ts +9 -1
- package/src/auth-plugin.ts +5 -22
- 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
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
+
|
|
3
|
+
import { ObjectSchema, Field } from '@objectstack/spec/data';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* sys_invitation — System Invitation Object
|
|
7
|
+
*
|
|
8
|
+
* Organization invitation tokens for inviting users.
|
|
9
|
+
* Backed by better-auth's organization plugin.
|
|
10
|
+
*
|
|
11
|
+
* @namespace sys
|
|
12
|
+
*/
|
|
13
|
+
export const SysInvitation = ObjectSchema.create({
|
|
14
|
+
namespace: 'sys',
|
|
15
|
+
name: 'invitation',
|
|
16
|
+
label: 'Invitation',
|
|
17
|
+
pluralLabel: 'Invitations',
|
|
18
|
+
icon: 'mail',
|
|
19
|
+
isSystem: true,
|
|
20
|
+
description: 'Organization invitations for user onboarding',
|
|
21
|
+
titleFormat: 'Invitation to {organization_id}',
|
|
22
|
+
compactLayout: ['email', 'organization_id', 'status'],
|
|
23
|
+
|
|
24
|
+
fields: {
|
|
25
|
+
id: Field.text({
|
|
26
|
+
label: 'Invitation ID',
|
|
27
|
+
required: true,
|
|
28
|
+
readonly: true,
|
|
29
|
+
}),
|
|
30
|
+
|
|
31
|
+
created_at: Field.datetime({
|
|
32
|
+
label: 'Created At',
|
|
33
|
+
defaultValue: 'NOW()',
|
|
34
|
+
readonly: true,
|
|
35
|
+
}),
|
|
36
|
+
|
|
37
|
+
organization_id: Field.text({
|
|
38
|
+
label: 'Organization ID',
|
|
39
|
+
required: true,
|
|
40
|
+
}),
|
|
41
|
+
|
|
42
|
+
email: Field.email({
|
|
43
|
+
label: 'Email',
|
|
44
|
+
required: true,
|
|
45
|
+
description: 'Email address of the invited user',
|
|
46
|
+
}),
|
|
47
|
+
|
|
48
|
+
role: Field.text({
|
|
49
|
+
label: 'Role',
|
|
50
|
+
required: false,
|
|
51
|
+
maxLength: 100,
|
|
52
|
+
description: 'Role to assign upon acceptance',
|
|
53
|
+
}),
|
|
54
|
+
|
|
55
|
+
status: Field.select(['pending', 'accepted', 'rejected', 'expired', 'canceled'], {
|
|
56
|
+
label: 'Status',
|
|
57
|
+
required: true,
|
|
58
|
+
defaultValue: 'pending',
|
|
59
|
+
}),
|
|
60
|
+
|
|
61
|
+
inviter_id: Field.text({
|
|
62
|
+
label: 'Inviter ID',
|
|
63
|
+
required: true,
|
|
64
|
+
description: 'User ID of the person who sent the invitation',
|
|
65
|
+
}),
|
|
66
|
+
|
|
67
|
+
expires_at: Field.datetime({
|
|
68
|
+
label: 'Expires At',
|
|
69
|
+
required: true,
|
|
70
|
+
}),
|
|
71
|
+
|
|
72
|
+
team_id: Field.text({
|
|
73
|
+
label: 'Team ID',
|
|
74
|
+
required: false,
|
|
75
|
+
description: 'Optional team to assign upon acceptance',
|
|
76
|
+
}),
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
indexes: [
|
|
80
|
+
{ fields: ['organization_id'] },
|
|
81
|
+
{ fields: ['email'] },
|
|
82
|
+
{ fields: ['expires_at'] },
|
|
83
|
+
],
|
|
84
|
+
|
|
85
|
+
enable: {
|
|
86
|
+
trackHistory: true,
|
|
87
|
+
searchable: false,
|
|
88
|
+
apiEnabled: true,
|
|
89
|
+
apiMethods: ['get', 'list', 'create', 'update', 'delete'],
|
|
90
|
+
trash: false,
|
|
91
|
+
mru: false,
|
|
92
|
+
},
|
|
93
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
+
|
|
3
|
+
import { ObjectSchema, Field } from '@objectstack/spec/data';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* sys_member — System Member Object
|
|
7
|
+
*
|
|
8
|
+
* Organization membership linking users to organizations with roles.
|
|
9
|
+
* Backed by better-auth's organization plugin.
|
|
10
|
+
*
|
|
11
|
+
* @namespace sys
|
|
12
|
+
*/
|
|
13
|
+
export const SysMember = ObjectSchema.create({
|
|
14
|
+
namespace: 'sys',
|
|
15
|
+
name: 'member',
|
|
16
|
+
label: 'Member',
|
|
17
|
+
pluralLabel: 'Members',
|
|
18
|
+
icon: 'user-check',
|
|
19
|
+
isSystem: true,
|
|
20
|
+
description: 'Organization membership records',
|
|
21
|
+
titleFormat: '{user_id} in {organization_id}',
|
|
22
|
+
compactLayout: ['user_id', 'organization_id', 'role'],
|
|
23
|
+
|
|
24
|
+
fields: {
|
|
25
|
+
id: Field.text({
|
|
26
|
+
label: 'Member ID',
|
|
27
|
+
required: true,
|
|
28
|
+
readonly: true,
|
|
29
|
+
}),
|
|
30
|
+
|
|
31
|
+
created_at: Field.datetime({
|
|
32
|
+
label: 'Created At',
|
|
33
|
+
defaultValue: 'NOW()',
|
|
34
|
+
readonly: true,
|
|
35
|
+
}),
|
|
36
|
+
|
|
37
|
+
organization_id: Field.text({
|
|
38
|
+
label: 'Organization ID',
|
|
39
|
+
required: true,
|
|
40
|
+
}),
|
|
41
|
+
|
|
42
|
+
user_id: Field.text({
|
|
43
|
+
label: 'User ID',
|
|
44
|
+
required: true,
|
|
45
|
+
}),
|
|
46
|
+
|
|
47
|
+
role: Field.text({
|
|
48
|
+
label: 'Role',
|
|
49
|
+
required: false,
|
|
50
|
+
description: 'Member role within the organization (e.g. admin, member)',
|
|
51
|
+
maxLength: 100,
|
|
52
|
+
}),
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
indexes: [
|
|
56
|
+
{ fields: ['organization_id', 'user_id'], unique: true },
|
|
57
|
+
{ fields: ['user_id'] },
|
|
58
|
+
],
|
|
59
|
+
|
|
60
|
+
enable: {
|
|
61
|
+
trackHistory: true,
|
|
62
|
+
searchable: false,
|
|
63
|
+
apiEnabled: true,
|
|
64
|
+
apiMethods: ['get', 'list', 'create', 'update', 'delete'],
|
|
65
|
+
trash: false,
|
|
66
|
+
mru: false,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
+
|
|
3
|
+
import { ObjectSchema, Field } from '@objectstack/spec/data';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* sys_organization — System Organization Object
|
|
7
|
+
*
|
|
8
|
+
* Multi-organization support for the ObjectStack platform.
|
|
9
|
+
* Backed by better-auth's organization plugin.
|
|
10
|
+
*
|
|
11
|
+
* @namespace sys
|
|
12
|
+
*/
|
|
13
|
+
export const SysOrganization = ObjectSchema.create({
|
|
14
|
+
namespace: 'sys',
|
|
15
|
+
name: 'organization',
|
|
16
|
+
label: 'Organization',
|
|
17
|
+
pluralLabel: 'Organizations',
|
|
18
|
+
icon: 'building-2',
|
|
19
|
+
isSystem: true,
|
|
20
|
+
description: 'Organizations for multi-tenant grouping',
|
|
21
|
+
titleFormat: '{name}',
|
|
22
|
+
compactLayout: ['name', 'slug', 'created_at'],
|
|
23
|
+
|
|
24
|
+
fields: {
|
|
25
|
+
id: Field.text({
|
|
26
|
+
label: 'Organization ID',
|
|
27
|
+
required: true,
|
|
28
|
+
readonly: true,
|
|
29
|
+
}),
|
|
30
|
+
|
|
31
|
+
created_at: Field.datetime({
|
|
32
|
+
label: 'Created At',
|
|
33
|
+
defaultValue: 'NOW()',
|
|
34
|
+
readonly: true,
|
|
35
|
+
}),
|
|
36
|
+
|
|
37
|
+
updated_at: Field.datetime({
|
|
38
|
+
label: 'Updated At',
|
|
39
|
+
defaultValue: 'NOW()',
|
|
40
|
+
readonly: true,
|
|
41
|
+
}),
|
|
42
|
+
|
|
43
|
+
name: Field.text({
|
|
44
|
+
label: 'Name',
|
|
45
|
+
required: true,
|
|
46
|
+
searchable: true,
|
|
47
|
+
maxLength: 255,
|
|
48
|
+
}),
|
|
49
|
+
|
|
50
|
+
slug: Field.text({
|
|
51
|
+
label: 'Slug',
|
|
52
|
+
required: false,
|
|
53
|
+
maxLength: 255,
|
|
54
|
+
description: 'URL-friendly identifier',
|
|
55
|
+
}),
|
|
56
|
+
|
|
57
|
+
logo: Field.url({
|
|
58
|
+
label: 'Logo',
|
|
59
|
+
required: false,
|
|
60
|
+
}),
|
|
61
|
+
|
|
62
|
+
metadata: Field.textarea({
|
|
63
|
+
label: 'Metadata',
|
|
64
|
+
required: false,
|
|
65
|
+
description: 'JSON-serialized organization metadata',
|
|
66
|
+
}),
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
indexes: [
|
|
70
|
+
{ fields: ['slug'], unique: true },
|
|
71
|
+
{ fields: ['name'] },
|
|
72
|
+
],
|
|
73
|
+
|
|
74
|
+
enable: {
|
|
75
|
+
trackHistory: true,
|
|
76
|
+
searchable: true,
|
|
77
|
+
apiEnabled: true,
|
|
78
|
+
apiMethods: ['get', 'list', 'create', 'update', 'delete'],
|
|
79
|
+
trash: true,
|
|
80
|
+
mru: true,
|
|
81
|
+
},
|
|
82
|
+
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
+
|
|
3
|
+
import { ObjectSchema, Field } from '@objectstack/spec/data';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* sys_session — System Session Object
|
|
7
|
+
*
|
|
8
|
+
* Active user session record for the ObjectStack platform.
|
|
9
|
+
* Backed by better-auth's `session` model with ObjectStack field conventions.
|
|
10
|
+
*
|
|
11
|
+
* @namespace sys
|
|
12
|
+
*/
|
|
13
|
+
export const SysSession = ObjectSchema.create({
|
|
14
|
+
namespace: 'sys',
|
|
15
|
+
name: 'session',
|
|
16
|
+
label: 'Session',
|
|
17
|
+
pluralLabel: 'Sessions',
|
|
18
|
+
icon: 'key',
|
|
19
|
+
isSystem: true,
|
|
20
|
+
description: 'Active user sessions',
|
|
21
|
+
titleFormat: 'Session {token}',
|
|
22
|
+
compactLayout: ['user_id', 'expires_at', 'ip_address'],
|
|
23
|
+
|
|
24
|
+
fields: {
|
|
25
|
+
id: Field.text({
|
|
26
|
+
label: 'Session ID',
|
|
27
|
+
required: true,
|
|
28
|
+
readonly: true,
|
|
29
|
+
}),
|
|
30
|
+
|
|
31
|
+
created_at: Field.datetime({
|
|
32
|
+
label: 'Created At',
|
|
33
|
+
defaultValue: 'NOW()',
|
|
34
|
+
readonly: true,
|
|
35
|
+
}),
|
|
36
|
+
|
|
37
|
+
updated_at: Field.datetime({
|
|
38
|
+
label: 'Updated At',
|
|
39
|
+
defaultValue: 'NOW()',
|
|
40
|
+
readonly: true,
|
|
41
|
+
}),
|
|
42
|
+
|
|
43
|
+
user_id: Field.text({
|
|
44
|
+
label: 'User ID',
|
|
45
|
+
required: true,
|
|
46
|
+
}),
|
|
47
|
+
|
|
48
|
+
expires_at: Field.datetime({
|
|
49
|
+
label: 'Expires At',
|
|
50
|
+
required: true,
|
|
51
|
+
}),
|
|
52
|
+
|
|
53
|
+
token: Field.text({
|
|
54
|
+
label: 'Session Token',
|
|
55
|
+
required: true,
|
|
56
|
+
}),
|
|
57
|
+
|
|
58
|
+
ip_address: Field.text({
|
|
59
|
+
label: 'IP Address',
|
|
60
|
+
required: false,
|
|
61
|
+
maxLength: 45, // Support IPv6
|
|
62
|
+
}),
|
|
63
|
+
|
|
64
|
+
user_agent: Field.textarea({
|
|
65
|
+
label: 'User Agent',
|
|
66
|
+
required: false,
|
|
67
|
+
}),
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
indexes: [
|
|
71
|
+
{ fields: ['token'], unique: true },
|
|
72
|
+
{ fields: ['user_id'], unique: false },
|
|
73
|
+
{ fields: ['expires_at'], unique: false },
|
|
74
|
+
],
|
|
75
|
+
|
|
76
|
+
enable: {
|
|
77
|
+
trackHistory: false,
|
|
78
|
+
searchable: false,
|
|
79
|
+
apiEnabled: true,
|
|
80
|
+
apiMethods: ['get', 'list', 'create', 'delete'],
|
|
81
|
+
trash: false,
|
|
82
|
+
mru: false,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
+
|
|
3
|
+
import { ObjectSchema, Field } from '@objectstack/spec/data';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* sys_team_member — System Team Member Object
|
|
7
|
+
*
|
|
8
|
+
* Links users to teams within organizations.
|
|
9
|
+
* Backed by better-auth's organization plugin (teams feature).
|
|
10
|
+
*
|
|
11
|
+
* @namespace sys
|
|
12
|
+
*/
|
|
13
|
+
export const SysTeamMember = ObjectSchema.create({
|
|
14
|
+
namespace: 'sys',
|
|
15
|
+
name: 'team_member',
|
|
16
|
+
label: 'Team Member',
|
|
17
|
+
pluralLabel: 'Team Members',
|
|
18
|
+
icon: 'user-plus',
|
|
19
|
+
isSystem: true,
|
|
20
|
+
description: 'Team membership records linking users to teams',
|
|
21
|
+
titleFormat: '{user_id} in {team_id}',
|
|
22
|
+
compactLayout: ['user_id', 'team_id', 'created_at'],
|
|
23
|
+
|
|
24
|
+
fields: {
|
|
25
|
+
id: Field.text({
|
|
26
|
+
label: 'Team Member ID',
|
|
27
|
+
required: true,
|
|
28
|
+
readonly: true,
|
|
29
|
+
}),
|
|
30
|
+
|
|
31
|
+
created_at: Field.datetime({
|
|
32
|
+
label: 'Created At',
|
|
33
|
+
defaultValue: 'NOW()',
|
|
34
|
+
readonly: true,
|
|
35
|
+
}),
|
|
36
|
+
|
|
37
|
+
team_id: Field.text({
|
|
38
|
+
label: 'Team ID',
|
|
39
|
+
required: true,
|
|
40
|
+
}),
|
|
41
|
+
|
|
42
|
+
user_id: Field.text({
|
|
43
|
+
label: 'User ID',
|
|
44
|
+
required: true,
|
|
45
|
+
}),
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
indexes: [
|
|
49
|
+
{ fields: ['team_id', 'user_id'], unique: true },
|
|
50
|
+
{ fields: ['user_id'] },
|
|
51
|
+
],
|
|
52
|
+
|
|
53
|
+
enable: {
|
|
54
|
+
trackHistory: true,
|
|
55
|
+
searchable: false,
|
|
56
|
+
apiEnabled: true,
|
|
57
|
+
apiMethods: ['get', 'list', 'create', 'delete'],
|
|
58
|
+
trash: false,
|
|
59
|
+
mru: false,
|
|
60
|
+
},
|
|
61
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
+
|
|
3
|
+
import { ObjectSchema, Field } from '@objectstack/spec/data';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* sys_team — System Team Object
|
|
7
|
+
*
|
|
8
|
+
* Teams within an organization for fine-grained grouping.
|
|
9
|
+
* Backed by better-auth's organization plugin (teams feature).
|
|
10
|
+
*
|
|
11
|
+
* @namespace sys
|
|
12
|
+
*/
|
|
13
|
+
export const SysTeam = ObjectSchema.create({
|
|
14
|
+
namespace: 'sys',
|
|
15
|
+
name: 'team',
|
|
16
|
+
label: 'Team',
|
|
17
|
+
pluralLabel: 'Teams',
|
|
18
|
+
icon: 'users',
|
|
19
|
+
isSystem: true,
|
|
20
|
+
description: 'Teams within organizations for fine-grained grouping',
|
|
21
|
+
titleFormat: '{name}',
|
|
22
|
+
compactLayout: ['name', 'organization_id', 'created_at'],
|
|
23
|
+
|
|
24
|
+
fields: {
|
|
25
|
+
id: Field.text({
|
|
26
|
+
label: 'Team ID',
|
|
27
|
+
required: true,
|
|
28
|
+
readonly: true,
|
|
29
|
+
}),
|
|
30
|
+
|
|
31
|
+
created_at: Field.datetime({
|
|
32
|
+
label: 'Created At',
|
|
33
|
+
defaultValue: 'NOW()',
|
|
34
|
+
readonly: true,
|
|
35
|
+
}),
|
|
36
|
+
|
|
37
|
+
updated_at: Field.datetime({
|
|
38
|
+
label: 'Updated At',
|
|
39
|
+
defaultValue: 'NOW()',
|
|
40
|
+
readonly: true,
|
|
41
|
+
}),
|
|
42
|
+
|
|
43
|
+
name: Field.text({
|
|
44
|
+
label: 'Name',
|
|
45
|
+
required: true,
|
|
46
|
+
searchable: true,
|
|
47
|
+
maxLength: 255,
|
|
48
|
+
}),
|
|
49
|
+
|
|
50
|
+
organization_id: Field.text({
|
|
51
|
+
label: 'Organization ID',
|
|
52
|
+
required: true,
|
|
53
|
+
}),
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
indexes: [
|
|
57
|
+
{ fields: ['organization_id'] },
|
|
58
|
+
{ fields: ['name', 'organization_id'], unique: true },
|
|
59
|
+
],
|
|
60
|
+
|
|
61
|
+
enable: {
|
|
62
|
+
trackHistory: true,
|
|
63
|
+
searchable: true,
|
|
64
|
+
apiEnabled: true,
|
|
65
|
+
apiMethods: ['get', 'list', 'create', 'update', 'delete'],
|
|
66
|
+
trash: true,
|
|
67
|
+
mru: false,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
+
|
|
3
|
+
import { ObjectSchema, Field } from '@objectstack/spec/data';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* sys_two_factor — System Two-Factor Object
|
|
7
|
+
*
|
|
8
|
+
* Two-factor authentication credentials (TOTP, backup codes).
|
|
9
|
+
* Backed by better-auth's two-factor plugin.
|
|
10
|
+
*
|
|
11
|
+
* @namespace sys
|
|
12
|
+
*/
|
|
13
|
+
export const SysTwoFactor = ObjectSchema.create({
|
|
14
|
+
namespace: 'sys',
|
|
15
|
+
name: 'two_factor',
|
|
16
|
+
label: 'Two Factor',
|
|
17
|
+
pluralLabel: 'Two Factor Credentials',
|
|
18
|
+
icon: 'smartphone',
|
|
19
|
+
isSystem: true,
|
|
20
|
+
description: 'Two-factor authentication credentials',
|
|
21
|
+
titleFormat: 'Two-factor for {user_id}',
|
|
22
|
+
compactLayout: ['user_id', 'created_at'],
|
|
23
|
+
|
|
24
|
+
fields: {
|
|
25
|
+
id: Field.text({
|
|
26
|
+
label: 'Two Factor ID',
|
|
27
|
+
required: true,
|
|
28
|
+
readonly: true,
|
|
29
|
+
}),
|
|
30
|
+
|
|
31
|
+
created_at: Field.datetime({
|
|
32
|
+
label: 'Created At',
|
|
33
|
+
defaultValue: 'NOW()',
|
|
34
|
+
readonly: true,
|
|
35
|
+
}),
|
|
36
|
+
|
|
37
|
+
updated_at: Field.datetime({
|
|
38
|
+
label: 'Updated At',
|
|
39
|
+
defaultValue: 'NOW()',
|
|
40
|
+
readonly: true,
|
|
41
|
+
}),
|
|
42
|
+
|
|
43
|
+
user_id: Field.text({
|
|
44
|
+
label: 'User ID',
|
|
45
|
+
required: true,
|
|
46
|
+
}),
|
|
47
|
+
|
|
48
|
+
secret: Field.text({
|
|
49
|
+
label: 'Secret',
|
|
50
|
+
required: true,
|
|
51
|
+
description: 'TOTP secret key',
|
|
52
|
+
}),
|
|
53
|
+
|
|
54
|
+
backup_codes: Field.textarea({
|
|
55
|
+
label: 'Backup Codes',
|
|
56
|
+
required: false,
|
|
57
|
+
description: 'JSON-serialized backup recovery codes',
|
|
58
|
+
}),
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
indexes: [
|
|
62
|
+
{ fields: ['user_id'], unique: true },
|
|
63
|
+
],
|
|
64
|
+
|
|
65
|
+
enable: {
|
|
66
|
+
trackHistory: false,
|
|
67
|
+
searchable: false,
|
|
68
|
+
apiEnabled: true,
|
|
69
|
+
apiMethods: ['get', 'create', 'update', 'delete'],
|
|
70
|
+
trash: false,
|
|
71
|
+
mru: false,
|
|
72
|
+
},
|
|
73
|
+
});
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
+
|
|
3
|
+
import { ObjectSchema, Field } from '@objectstack/spec/data';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* sys_user — System User Object
|
|
7
|
+
*
|
|
8
|
+
* Canonical user identity record for the ObjectStack platform.
|
|
9
|
+
* Backed by better-auth's `user` model with ObjectStack field conventions.
|
|
10
|
+
*
|
|
11
|
+
* @namespace sys
|
|
12
|
+
*/
|
|
13
|
+
export const SysUser = ObjectSchema.create({
|
|
14
|
+
namespace: 'sys',
|
|
15
|
+
name: 'user',
|
|
16
|
+
label: 'User',
|
|
17
|
+
pluralLabel: 'Users',
|
|
18
|
+
icon: 'user',
|
|
19
|
+
isSystem: true,
|
|
20
|
+
description: 'User accounts for authentication',
|
|
21
|
+
titleFormat: '{name} ({email})',
|
|
22
|
+
compactLayout: ['name', 'email', 'email_verified'],
|
|
23
|
+
|
|
24
|
+
fields: {
|
|
25
|
+
id: Field.text({
|
|
26
|
+
label: 'User ID',
|
|
27
|
+
required: true,
|
|
28
|
+
readonly: true,
|
|
29
|
+
}),
|
|
30
|
+
|
|
31
|
+
created_at: Field.datetime({
|
|
32
|
+
label: 'Created At',
|
|
33
|
+
defaultValue: 'NOW()',
|
|
34
|
+
readonly: true,
|
|
35
|
+
}),
|
|
36
|
+
|
|
37
|
+
updated_at: Field.datetime({
|
|
38
|
+
label: 'Updated At',
|
|
39
|
+
defaultValue: 'NOW()',
|
|
40
|
+
readonly: true,
|
|
41
|
+
}),
|
|
42
|
+
|
|
43
|
+
email: Field.email({
|
|
44
|
+
label: 'Email',
|
|
45
|
+
required: true,
|
|
46
|
+
searchable: true,
|
|
47
|
+
}),
|
|
48
|
+
|
|
49
|
+
email_verified: Field.boolean({
|
|
50
|
+
label: 'Email Verified',
|
|
51
|
+
defaultValue: false,
|
|
52
|
+
}),
|
|
53
|
+
|
|
54
|
+
name: Field.text({
|
|
55
|
+
label: 'Name',
|
|
56
|
+
required: true,
|
|
57
|
+
searchable: true,
|
|
58
|
+
maxLength: 255,
|
|
59
|
+
}),
|
|
60
|
+
|
|
61
|
+
image: Field.url({
|
|
62
|
+
label: 'Profile Image',
|
|
63
|
+
required: false,
|
|
64
|
+
}),
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
indexes: [
|
|
68
|
+
{ fields: ['email'], unique: true },
|
|
69
|
+
{ fields: ['created_at'], unique: false },
|
|
70
|
+
],
|
|
71
|
+
|
|
72
|
+
enable: {
|
|
73
|
+
trackHistory: true,
|
|
74
|
+
searchable: true,
|
|
75
|
+
apiEnabled: true,
|
|
76
|
+
apiMethods: ['get', 'list', 'create', 'update', 'delete'],
|
|
77
|
+
trash: true,
|
|
78
|
+
mru: true,
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
validations: [
|
|
82
|
+
{
|
|
83
|
+
name: 'email_unique',
|
|
84
|
+
type: 'unique',
|
|
85
|
+
severity: 'error',
|
|
86
|
+
message: 'Email must be unique',
|
|
87
|
+
fields: ['email'],
|
|
88
|
+
caseSensitive: false,
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
|
|
2
|
+
|
|
3
|
+
import { ObjectSchema, Field } from '@objectstack/spec/data';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* sys_verification — System Verification Object
|
|
7
|
+
*
|
|
8
|
+
* Email and phone verification token record.
|
|
9
|
+
* Backed by better-auth's `verification` model with ObjectStack field conventions.
|
|
10
|
+
*
|
|
11
|
+
* @namespace sys
|
|
12
|
+
*/
|
|
13
|
+
export const SysVerification = ObjectSchema.create({
|
|
14
|
+
namespace: 'sys',
|
|
15
|
+
name: 'verification',
|
|
16
|
+
label: 'Verification',
|
|
17
|
+
pluralLabel: 'Verifications',
|
|
18
|
+
icon: 'shield-check',
|
|
19
|
+
isSystem: true,
|
|
20
|
+
description: 'Email and phone verification tokens',
|
|
21
|
+
titleFormat: 'Verification for {identifier}',
|
|
22
|
+
compactLayout: ['identifier', 'expires_at', 'created_at'],
|
|
23
|
+
|
|
24
|
+
fields: {
|
|
25
|
+
id: Field.text({
|
|
26
|
+
label: 'Verification ID',
|
|
27
|
+
required: true,
|
|
28
|
+
readonly: true,
|
|
29
|
+
}),
|
|
30
|
+
|
|
31
|
+
created_at: Field.datetime({
|
|
32
|
+
label: 'Created At',
|
|
33
|
+
defaultValue: 'NOW()',
|
|
34
|
+
readonly: true,
|
|
35
|
+
}),
|
|
36
|
+
|
|
37
|
+
updated_at: Field.datetime({
|
|
38
|
+
label: 'Updated At',
|
|
39
|
+
defaultValue: 'NOW()',
|
|
40
|
+
readonly: true,
|
|
41
|
+
}),
|
|
42
|
+
|
|
43
|
+
value: Field.text({
|
|
44
|
+
label: 'Verification Token',
|
|
45
|
+
required: true,
|
|
46
|
+
description: 'Token or code for verification',
|
|
47
|
+
}),
|
|
48
|
+
|
|
49
|
+
expires_at: Field.datetime({
|
|
50
|
+
label: 'Expires At',
|
|
51
|
+
required: true,
|
|
52
|
+
}),
|
|
53
|
+
|
|
54
|
+
identifier: Field.text({
|
|
55
|
+
label: 'Identifier',
|
|
56
|
+
required: true,
|
|
57
|
+
description: 'Email address or phone number',
|
|
58
|
+
}),
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
indexes: [
|
|
62
|
+
{ fields: ['value'], unique: true },
|
|
63
|
+
{ fields: ['identifier'], unique: false },
|
|
64
|
+
{ fields: ['expires_at'], unique: false },
|
|
65
|
+
],
|
|
66
|
+
|
|
67
|
+
enable: {
|
|
68
|
+
trackHistory: false,
|
|
69
|
+
searchable: false,
|
|
70
|
+
apiEnabled: true,
|
|
71
|
+
apiMethods: ['get', 'create', 'delete'],
|
|
72
|
+
trash: false,
|
|
73
|
+
mru: false,
|
|
74
|
+
},
|
|
75
|
+
});
|