@objectstack/plugin-auth 3.2.5 → 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.
@@ -1,89 +1,7 @@
1
1
  // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2
2
 
3
- import { ObjectSchema, Field } from '@objectstack/spec/data';
4
-
5
3
  /**
6
- * Auth Session Object
7
- *
8
- * Uses better-auth's native schema for seamless migration:
9
- * - id: string
10
- * - created_at: Date
11
- * - updated_at: Date
12
- * - user_id: string
13
- * - expires_at: Date
14
- * - token: string
15
- * - ip_address: string | null
16
- * - user_agent: string | null
4
+ * @deprecated Use `SysSession` from `./sys-session.object` instead.
5
+ * This re-export is kept for backward compatibility.
17
6
  */
18
- export const AuthSession = ObjectSchema.create({
19
- name: 'sys_session',
20
- label: 'Session',
21
- pluralLabel: 'Sessions',
22
- icon: 'key',
23
- description: 'Active user sessions',
24
- titleFormat: 'Session {token}',
25
- compactLayout: ['user_id', 'expires_at', 'ip_address'],
26
-
27
- fields: {
28
- id: Field.text({
29
- label: 'Session ID',
30
- required: true,
31
- readonly: true,
32
- }),
33
-
34
- created_at: Field.datetime({
35
- label: 'Created At',
36
- defaultValue: 'NOW()',
37
- readonly: true,
38
- }),
39
-
40
- updated_at: Field.datetime({
41
- label: 'Updated At',
42
- defaultValue: 'NOW()',
43
- readonly: true,
44
- }),
45
-
46
- user_id: Field.text({
47
- label: 'User ID',
48
- required: true,
49
- }),
50
-
51
- expires_at: Field.datetime({
52
- label: 'Expires At',
53
- required: true,
54
- }),
55
-
56
- token: Field.text({
57
- label: 'Session Token',
58
- required: true,
59
- }),
60
-
61
- ip_address: Field.text({
62
- label: 'IP Address',
63
- required: false,
64
- maxLength: 45, // Support IPv6
65
- }),
66
-
67
- user_agent: Field.textarea({
68
- label: 'User Agent',
69
- required: false,
70
- }),
71
- },
72
-
73
- // Database indexes for performance
74
- indexes: [
75
- { fields: ['token'], unique: true },
76
- { fields: ['user_id'], unique: false },
77
- { fields: ['expires_at'], unique: false },
78
- ],
79
-
80
- // Enable features
81
- enable: {
82
- trackHistory: false, // Sessions don't need history tracking
83
- searchable: false,
84
- apiEnabled: true,
85
- apiMethods: ['get', 'list', 'create', 'delete'], // No update for sessions
86
- trash: false, // Sessions should be hard deleted
87
- mru: false,
88
- },
89
- });
7
+ export { SysSession as AuthSession } from './sys-session.object.js';
@@ -1,97 +1,7 @@
1
1
  // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2
2
 
3
- import { ObjectSchema, Field } from '@objectstack/spec/data';
4
-
5
3
  /**
6
- * Auth User Object
7
- *
8
- * Uses better-auth's native schema for seamless migration:
9
- * - id: string
10
- * - created_at: Date
11
- * - updated_at: Date
12
- * - email: string (unique, lowercase)
13
- * - email_verified: boolean
14
- * - name: string
15
- * - image: string | null
4
+ * @deprecated Use `SysUser` from `./sys-user.object` instead.
5
+ * This re-export is kept for backward compatibility.
16
6
  */
17
- export const AuthUser = ObjectSchema.create({
18
- name: 'sys_user',
19
- label: 'User',
20
- pluralLabel: 'Users',
21
- icon: 'user',
22
- description: 'User accounts for authentication',
23
- titleFormat: '{name} ({email})',
24
- compactLayout: ['name', 'email', 'email_verified'],
25
-
26
- fields: {
27
- // ID is auto-generated by ObjectQL
28
- id: Field.text({
29
- label: 'User ID',
30
- required: true,
31
- readonly: true,
32
- }),
33
-
34
- created_at: Field.datetime({
35
- label: 'Created At',
36
- defaultValue: 'NOW()',
37
- readonly: true,
38
- }),
39
-
40
- updated_at: Field.datetime({
41
- label: 'Updated At',
42
- defaultValue: 'NOW()',
43
- readonly: true,
44
- }),
45
-
46
- email: Field.email({
47
- label: 'Email',
48
- required: true,
49
- searchable: true,
50
- }),
51
-
52
- email_verified: Field.boolean({
53
- label: 'Email Verified',
54
- defaultValue: false,
55
- }),
56
-
57
- name: Field.text({
58
- label: 'Name',
59
- required: true,
60
- searchable: true,
61
- maxLength: 255,
62
- }),
63
-
64
- image: Field.url({
65
- label: 'Profile Image',
66
- required: false,
67
- }),
68
- },
69
-
70
- // Database indexes for performance
71
- indexes: [
72
- { fields: ['email'], unique: true },
73
- { fields: ['created_at'], unique: false },
74
- ],
75
-
76
- // Enable features
77
- enable: {
78
- trackHistory: true,
79
- searchable: true,
80
- apiEnabled: true,
81
- apiMethods: ['get', 'list', 'create', 'update', 'delete'],
82
- trash: true,
83
- mru: true,
84
- },
85
-
86
- // Validation Rules
87
- validations: [
88
- {
89
- name: 'email_unique',
90
- type: 'unique',
91
- severity: 'error',
92
- message: 'Email must be unique',
93
- fields: ['email'],
94
- caseSensitive: false,
95
- },
96
- ],
97
- });
7
+ export { SysUser as AuthUser } from './sys-user.object.js';
@@ -1,78 +1,7 @@
1
1
  // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2
2
 
3
- import { ObjectSchema, Field } from '@objectstack/spec/data';
4
-
5
3
  /**
6
- * Auth Verification Object
7
- *
8
- * Uses better-auth's native schema for seamless migration:
9
- * - id: string
10
- * - created_at: Date
11
- * - updated_at: Date
12
- * - value: string (verification token/code)
13
- * - expires_at: Date
14
- * - identifier: string (email or phone number)
4
+ * @deprecated Use `SysVerification` from `./sys-verification.object` instead.
5
+ * This re-export is kept for backward compatibility.
15
6
  */
16
- export const AuthVerification = ObjectSchema.create({
17
- name: 'sys_verification',
18
- label: 'Verification',
19
- pluralLabel: 'Verifications',
20
- icon: 'shield-check',
21
- description: 'Email and phone verification tokens',
22
- titleFormat: 'Verification for {identifier}',
23
- compactLayout: ['identifier', 'expires_at', 'created_at'],
24
-
25
- fields: {
26
- id: Field.text({
27
- label: 'Verification ID',
28
- required: true,
29
- readonly: true,
30
- }),
31
-
32
- created_at: Field.datetime({
33
- label: 'Created At',
34
- defaultValue: 'NOW()',
35
- readonly: true,
36
- }),
37
-
38
- updated_at: Field.datetime({
39
- label: 'Updated At',
40
- defaultValue: 'NOW()',
41
- readonly: true,
42
- }),
43
-
44
- value: Field.text({
45
- label: 'Verification Token',
46
- required: true,
47
- description: 'Token or code for verification',
48
- }),
49
-
50
- expires_at: Field.datetime({
51
- label: 'Expires At',
52
- required: true,
53
- }),
54
-
55
- identifier: Field.text({
56
- label: 'Identifier',
57
- required: true,
58
- description: 'Email address or phone number',
59
- }),
60
- },
61
-
62
- // Database indexes for performance
63
- indexes: [
64
- { fields: ['value'], unique: true },
65
- { fields: ['identifier'], unique: false },
66
- { fields: ['expires_at'], unique: false },
67
- ],
68
-
69
- // Enable features
70
- enable: {
71
- trackHistory: false,
72
- searchable: false,
73
- apiEnabled: true,
74
- apiMethods: ['get', 'create', 'delete'], // No list or update
75
- trash: false, // Hard delete expired tokens
76
- mru: false,
77
- },
78
- });
7
+ export { SysVerification as AuthVerification } from './sys-verification.object.js';
@@ -1,13 +1,39 @@
1
1
  // Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
2
2
 
3
3
  /**
4
- * Auth Objects
5
- *
6
- * ObjectQL-based object definitions for authentication database schema.
7
- * These objects replace the need for third-party ORMs like drizzle-orm.
4
+ * Auth Plugin — System Object Definitions (sys namespace)
5
+ *
6
+ * Canonical ObjectSchema definitions for all authentication-related system objects.
7
+ * All objects belong to the `sys` namespace and follow the unified naming convention:
8
+ * - File: `sys-{name}.object.ts`
9
+ * - Export: `Sys{PascalCase}`
10
+ * - Object name: `{name}` (snake_case, no prefix)
11
+ * - Table name: `sys_{name}` (auto-derived from namespace)
8
12
  */
9
13
 
14
+ // ── Core Auth Objects ──────────────────────────────────────────────────────
15
+ export { SysUser } from './sys-user.object.js';
16
+ export { SysSession } from './sys-session.object.js';
17
+ export { SysAccount } from './sys-account.object.js';
18
+ export { SysVerification } from './sys-verification.object.js';
19
+
20
+ // ── Organization Objects ───────────────────────────────────────────────────
21
+ export { SysOrganization } from './sys-organization.object.js';
22
+ export { SysMember } from './sys-member.object.js';
23
+ export { SysInvitation } from './sys-invitation.object.js';
24
+ export { SysTeam } from './sys-team.object.js';
25
+ export { SysTeamMember } from './sys-team-member.object.js';
26
+
27
+ // ── Additional Auth Objects ────────────────────────────────────────────────
28
+ export { SysApiKey } from './sys-api-key.object.js';
29
+ export { SysTwoFactor } from './sys-two-factor.object.js';
30
+
31
+ // ── Backward Compatibility (deprecated) ────────────────────────────────────
32
+ /** @deprecated Use `SysUser` instead */
10
33
  export { AuthUser } from './auth-user.object.js';
34
+ /** @deprecated Use `SysSession` instead */
11
35
  export { AuthSession } from './auth-session.object.js';
36
+ /** @deprecated Use `SysAccount` instead */
12
37
  export { AuthAccount } from './auth-account.object.js';
38
+ /** @deprecated Use `SysVerification` instead */
13
39
  export { AuthVerification } from './auth-verification.object.js';
@@ -0,0 +1,111 @@
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_account — System Account Object
7
+ *
8
+ * OAuth / credential provider account record.
9
+ * Backed by better-auth's `account` model with ObjectStack field conventions.
10
+ *
11
+ * @namespace sys
12
+ */
13
+ export const SysAccount = ObjectSchema.create({
14
+ namespace: 'sys',
15
+ name: 'account',
16
+ label: 'Account',
17
+ pluralLabel: 'Accounts',
18
+ icon: 'link',
19
+ isSystem: true,
20
+ description: 'OAuth and authentication provider accounts',
21
+ titleFormat: '{provider_id} - {account_id}',
22
+ compactLayout: ['provider_id', 'user_id', 'account_id'],
23
+
24
+ fields: {
25
+ id: Field.text({
26
+ label: 'Account 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
+ provider_id: Field.text({
44
+ label: 'Provider ID',
45
+ required: true,
46
+ description: 'OAuth provider identifier (google, github, etc.)',
47
+ }),
48
+
49
+ account_id: Field.text({
50
+ label: 'Provider Account ID',
51
+ required: true,
52
+ description: "User's ID in the provider's system",
53
+ }),
54
+
55
+ user_id: Field.text({
56
+ label: 'User ID',
57
+ required: true,
58
+ description: 'Link to user table',
59
+ }),
60
+
61
+ access_token: Field.textarea({
62
+ label: 'Access Token',
63
+ required: false,
64
+ }),
65
+
66
+ refresh_token: Field.textarea({
67
+ label: 'Refresh Token',
68
+ required: false,
69
+ }),
70
+
71
+ id_token: Field.textarea({
72
+ label: 'ID Token',
73
+ required: false,
74
+ }),
75
+
76
+ access_token_expires_at: Field.datetime({
77
+ label: 'Access Token Expires At',
78
+ required: false,
79
+ }),
80
+
81
+ refresh_token_expires_at: Field.datetime({
82
+ label: 'Refresh Token Expires At',
83
+ required: false,
84
+ }),
85
+
86
+ scope: Field.text({
87
+ label: 'OAuth Scope',
88
+ required: false,
89
+ }),
90
+
91
+ password: Field.text({
92
+ label: 'Password Hash',
93
+ required: false,
94
+ description: 'Hashed password for email/password provider',
95
+ }),
96
+ },
97
+
98
+ indexes: [
99
+ { fields: ['user_id'], unique: false },
100
+ { fields: ['provider_id', 'account_id'], unique: true },
101
+ ],
102
+
103
+ enable: {
104
+ trackHistory: false,
105
+ searchable: false,
106
+ apiEnabled: true,
107
+ apiMethods: ['get', 'list', 'create', 'update', 'delete'],
108
+ trash: true,
109
+ mru: false,
110
+ },
111
+ });
@@ -0,0 +1,104 @@
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_api_key — System API Key Object
7
+ *
8
+ * API keys for programmatic/machine access to the platform.
9
+ *
10
+ * @namespace sys
11
+ */
12
+ export const SysApiKey = ObjectSchema.create({
13
+ namespace: 'sys',
14
+ name: 'api_key',
15
+ label: 'API Key',
16
+ pluralLabel: 'API Keys',
17
+ icon: 'key-round',
18
+ isSystem: true,
19
+ description: 'API keys for programmatic access',
20
+ titleFormat: '{name}',
21
+ compactLayout: ['name', 'user_id', 'expires_at'],
22
+
23
+ fields: {
24
+ id: Field.text({
25
+ label: 'API Key ID',
26
+ required: true,
27
+ readonly: true,
28
+ }),
29
+
30
+ created_at: Field.datetime({
31
+ label: 'Created At',
32
+ defaultValue: 'NOW()',
33
+ readonly: true,
34
+ }),
35
+
36
+ updated_at: Field.datetime({
37
+ label: 'Updated At',
38
+ defaultValue: 'NOW()',
39
+ readonly: true,
40
+ }),
41
+
42
+ name: Field.text({
43
+ label: 'Name',
44
+ required: true,
45
+ maxLength: 255,
46
+ description: 'Human-readable label for the API key',
47
+ }),
48
+
49
+ key: Field.text({
50
+ label: 'Key',
51
+ required: true,
52
+ description: 'Hashed API key value',
53
+ }),
54
+
55
+ prefix: Field.text({
56
+ label: 'Prefix',
57
+ required: false,
58
+ maxLength: 16,
59
+ description: 'Visible prefix for identifying the key (e.g., "osk_")',
60
+ }),
61
+
62
+ user_id: Field.text({
63
+ label: 'User ID',
64
+ required: true,
65
+ description: 'Owner user of this API key',
66
+ }),
67
+
68
+ scopes: Field.textarea({
69
+ label: 'Scopes',
70
+ required: false,
71
+ description: 'JSON array of permission scopes',
72
+ }),
73
+
74
+ expires_at: Field.datetime({
75
+ label: 'Expires At',
76
+ required: false,
77
+ }),
78
+
79
+ last_used_at: Field.datetime({
80
+ label: 'Last Used At',
81
+ required: false,
82
+ }),
83
+
84
+ revoked: Field.boolean({
85
+ label: 'Revoked',
86
+ defaultValue: false,
87
+ }),
88
+ },
89
+
90
+ indexes: [
91
+ { fields: ['key'], unique: true },
92
+ { fields: ['user_id'] },
93
+ { fields: ['prefix'] },
94
+ ],
95
+
96
+ enable: {
97
+ trackHistory: true,
98
+ searchable: false,
99
+ apiEnabled: true,
100
+ apiMethods: ['get', 'list', 'create', 'update', 'delete'],
101
+ trash: false,
102
+ mru: false,
103
+ },
104
+ });
@@ -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
+ });