@objectstack/platform-objects 0.1.0
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/LICENSE +202 -0
- package/dist/apps/index.d.mts +427 -0
- package/dist/apps/index.d.ts +427 -0
- package/dist/apps/index.js +520 -0
- package/dist/apps/index.js.map +1 -0
- package/dist/apps/index.mjs +510 -0
- package/dist/apps/index.mjs.map +1 -0
- package/dist/audit/index.d.mts +9507 -0
- package/dist/audit/index.d.ts +9507 -0
- package/dist/audit/index.js +492 -0
- package/dist/audit/index.js.map +1 -0
- package/dist/audit/index.mjs +487 -0
- package/dist/audit/index.mjs.map +1 -0
- package/dist/identity/index.d.mts +32482 -0
- package/dist/identity/index.d.ts +32482 -0
- package/dist/identity/index.js +1404 -0
- package/dist/identity/index.js.map +1 -0
- package/dist/identity/index.mjs +1385 -0
- package/dist/identity/index.mjs.map +1 -0
- package/dist/index.d.mts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +4209 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +4160 -0
- package/dist/index.mjs.map +1 -0
- package/dist/metadata/index.d.mts +25601 -0
- package/dist/metadata/index.d.ts +25601 -0
- package/dist/metadata/index.js +911 -0
- package/dist/metadata/index.js.map +1 -0
- package/dist/metadata/index.mjs +902 -0
- package/dist/metadata/index.mjs.map +1 -0
- package/dist/security/index.d.mts +3554 -0
- package/dist/security/index.d.ts +3554 -0
- package/dist/security/index.js +178 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/index.mjs +175 -0
- package/dist/security/index.mjs.map +1 -0
- package/dist/state-machine.zod-BFg-VE0M.d-Ek3_yo9P.d.mts +41 -0
- package/dist/state-machine.zod-BFg-VE0M.d-Ek3_yo9P.d.ts +41 -0
- package/dist/tenant/index.d.mts +16454 -0
- package/dist/tenant/index.d.ts +16454 -0
- package/dist/tenant/index.js +741 -0
- package/dist/tenant/index.js.map +1 -0
- package/dist/tenant/index.mjs +733 -0
- package/dist/tenant/index.mjs.map +1 -0
- package/package.json +84 -0
|
@@ -0,0 +1,1385 @@
|
|
|
1
|
+
import { ObjectSchema, Field } from '@objectstack/spec/data';
|
|
2
|
+
|
|
3
|
+
// src/identity/sys-user.object.ts
|
|
4
|
+
var SysUser = ObjectSchema.create({
|
|
5
|
+
name: "sys_user",
|
|
6
|
+
label: "User",
|
|
7
|
+
pluralLabel: "Users",
|
|
8
|
+
icon: "user",
|
|
9
|
+
isSystem: true,
|
|
10
|
+
description: "User accounts for authentication",
|
|
11
|
+
displayNameField: "name",
|
|
12
|
+
titleFormat: "{name}",
|
|
13
|
+
compactLayout: ["name", "email", "email_verified"],
|
|
14
|
+
fields: {
|
|
15
|
+
// ── Identity (primary business fields) ───────────────────────
|
|
16
|
+
name: Field.text({
|
|
17
|
+
label: "Name",
|
|
18
|
+
required: true,
|
|
19
|
+
searchable: true,
|
|
20
|
+
maxLength: 255,
|
|
21
|
+
group: "Identity"
|
|
22
|
+
}),
|
|
23
|
+
email: Field.email({
|
|
24
|
+
label: "Email",
|
|
25
|
+
required: true,
|
|
26
|
+
searchable: true,
|
|
27
|
+
group: "Identity"
|
|
28
|
+
}),
|
|
29
|
+
email_verified: Field.boolean({
|
|
30
|
+
label: "Email Verified",
|
|
31
|
+
defaultValue: false,
|
|
32
|
+
group: "Identity"
|
|
33
|
+
}),
|
|
34
|
+
two_factor_enabled: Field.boolean({
|
|
35
|
+
label: "Two-Factor Enabled",
|
|
36
|
+
defaultValue: false,
|
|
37
|
+
group: "Identity",
|
|
38
|
+
description: "Whether two-factor authentication is enabled for this user. Maintained by the better-auth `twoFactor` plugin."
|
|
39
|
+
}),
|
|
40
|
+
// ── Profile ──────────────────────────────────────────────────
|
|
41
|
+
image: Field.url({
|
|
42
|
+
label: "Profile Image",
|
|
43
|
+
required: false,
|
|
44
|
+
group: "Profile"
|
|
45
|
+
}),
|
|
46
|
+
// ── System (auto-managed, hidden from create/edit forms) ─────
|
|
47
|
+
id: Field.text({
|
|
48
|
+
label: "User ID",
|
|
49
|
+
required: true,
|
|
50
|
+
readonly: true,
|
|
51
|
+
group: "System"
|
|
52
|
+
}),
|
|
53
|
+
created_at: Field.datetime({
|
|
54
|
+
label: "Created At",
|
|
55
|
+
defaultValue: "NOW()",
|
|
56
|
+
readonly: true,
|
|
57
|
+
group: "System"
|
|
58
|
+
}),
|
|
59
|
+
updated_at: Field.datetime({
|
|
60
|
+
label: "Updated At",
|
|
61
|
+
defaultValue: "NOW()",
|
|
62
|
+
readonly: true,
|
|
63
|
+
group: "System"
|
|
64
|
+
})
|
|
65
|
+
},
|
|
66
|
+
indexes: [
|
|
67
|
+
{ fields: ["email"], unique: true },
|
|
68
|
+
{ fields: ["created_at"], unique: false }
|
|
69
|
+
],
|
|
70
|
+
enable: {
|
|
71
|
+
trackHistory: true,
|
|
72
|
+
searchable: true,
|
|
73
|
+
apiEnabled: true,
|
|
74
|
+
apiMethods: ["get", "list", "create", "update", "delete"],
|
|
75
|
+
trash: true,
|
|
76
|
+
mru: true
|
|
77
|
+
},
|
|
78
|
+
validations: [
|
|
79
|
+
{
|
|
80
|
+
name: "email_unique",
|
|
81
|
+
type: "unique",
|
|
82
|
+
severity: "error",
|
|
83
|
+
message: "Email must be unique",
|
|
84
|
+
fields: ["email"],
|
|
85
|
+
caseSensitive: false
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
});
|
|
89
|
+
var SysSession = ObjectSchema.create({
|
|
90
|
+
name: "sys_session",
|
|
91
|
+
label: "Session",
|
|
92
|
+
pluralLabel: "Sessions",
|
|
93
|
+
icon: "key",
|
|
94
|
+
isSystem: true,
|
|
95
|
+
description: "Active user sessions",
|
|
96
|
+
displayNameField: "user_id",
|
|
97
|
+
titleFormat: "Session \u2014 {user_id}",
|
|
98
|
+
compactLayout: ["user_id", "ip_address", "expires_at"],
|
|
99
|
+
fields: {
|
|
100
|
+
// ── Session owner & expiry ──────────────────────────────────
|
|
101
|
+
user_id: Field.lookup("sys_user", {
|
|
102
|
+
label: "User",
|
|
103
|
+
required: true,
|
|
104
|
+
searchable: true,
|
|
105
|
+
group: "Session"
|
|
106
|
+
}),
|
|
107
|
+
expires_at: Field.datetime({
|
|
108
|
+
label: "Expires At",
|
|
109
|
+
required: true,
|
|
110
|
+
group: "Session"
|
|
111
|
+
}),
|
|
112
|
+
// ── Active context (multi-org/team) ──────────────────────────
|
|
113
|
+
active_organization_id: Field.lookup("sys_organization", {
|
|
114
|
+
label: "Active Organization",
|
|
115
|
+
required: false,
|
|
116
|
+
group: "Context"
|
|
117
|
+
}),
|
|
118
|
+
active_team_id: Field.lookup("sys_team", {
|
|
119
|
+
label: "Active Team",
|
|
120
|
+
required: false,
|
|
121
|
+
group: "Context"
|
|
122
|
+
}),
|
|
123
|
+
// ── Client fingerprint ───────────────────────────────────────
|
|
124
|
+
ip_address: Field.text({
|
|
125
|
+
label: "IP Address",
|
|
126
|
+
required: false,
|
|
127
|
+
maxLength: 45,
|
|
128
|
+
// Support IPv6
|
|
129
|
+
group: "Client"
|
|
130
|
+
}),
|
|
131
|
+
user_agent: Field.textarea({
|
|
132
|
+
label: "User Agent",
|
|
133
|
+
required: false,
|
|
134
|
+
group: "Client"
|
|
135
|
+
}),
|
|
136
|
+
// ── Secret (hidden by default) ──────────────────────────────
|
|
137
|
+
token: Field.text({
|
|
138
|
+
label: "Session Token",
|
|
139
|
+
required: true,
|
|
140
|
+
hidden: true,
|
|
141
|
+
readonly: true,
|
|
142
|
+
description: "Opaque session token \u2014 never exposed in UI",
|
|
143
|
+
group: "Secret"
|
|
144
|
+
}),
|
|
145
|
+
// ── System ───────────────────────────────────────────────────
|
|
146
|
+
id: Field.text({
|
|
147
|
+
label: "Session ID",
|
|
148
|
+
required: true,
|
|
149
|
+
readonly: true,
|
|
150
|
+
group: "System"
|
|
151
|
+
}),
|
|
152
|
+
created_at: Field.datetime({
|
|
153
|
+
label: "Created At",
|
|
154
|
+
defaultValue: "NOW()",
|
|
155
|
+
readonly: true,
|
|
156
|
+
group: "System"
|
|
157
|
+
}),
|
|
158
|
+
updated_at: Field.datetime({
|
|
159
|
+
label: "Updated At",
|
|
160
|
+
defaultValue: "NOW()",
|
|
161
|
+
readonly: true,
|
|
162
|
+
group: "System"
|
|
163
|
+
})
|
|
164
|
+
},
|
|
165
|
+
indexes: [
|
|
166
|
+
{ fields: ["token"], unique: true },
|
|
167
|
+
{ fields: ["user_id"], unique: false },
|
|
168
|
+
{ fields: ["expires_at"], unique: false }
|
|
169
|
+
],
|
|
170
|
+
enable: {
|
|
171
|
+
trackHistory: false,
|
|
172
|
+
searchable: false,
|
|
173
|
+
apiEnabled: true,
|
|
174
|
+
apiMethods: ["get", "list", "create", "delete"],
|
|
175
|
+
trash: false,
|
|
176
|
+
mru: false,
|
|
177
|
+
clone: false
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
var SysAccount = ObjectSchema.create({
|
|
181
|
+
name: "sys_account",
|
|
182
|
+
label: "Account",
|
|
183
|
+
pluralLabel: "Accounts",
|
|
184
|
+
icon: "link",
|
|
185
|
+
isSystem: true,
|
|
186
|
+
description: "OAuth and authentication provider accounts",
|
|
187
|
+
titleFormat: "{provider_id} - {account_id}",
|
|
188
|
+
compactLayout: ["provider_id", "user_id", "account_id"],
|
|
189
|
+
fields: {
|
|
190
|
+
id: Field.text({
|
|
191
|
+
label: "Account ID",
|
|
192
|
+
required: true,
|
|
193
|
+
readonly: true
|
|
194
|
+
}),
|
|
195
|
+
created_at: Field.datetime({
|
|
196
|
+
label: "Created At",
|
|
197
|
+
defaultValue: "NOW()",
|
|
198
|
+
readonly: true
|
|
199
|
+
}),
|
|
200
|
+
updated_at: Field.datetime({
|
|
201
|
+
label: "Updated At",
|
|
202
|
+
defaultValue: "NOW()",
|
|
203
|
+
readonly: true
|
|
204
|
+
}),
|
|
205
|
+
provider_id: Field.text({
|
|
206
|
+
label: "Provider ID",
|
|
207
|
+
required: true,
|
|
208
|
+
description: "OAuth provider identifier (google, github, etc.)"
|
|
209
|
+
}),
|
|
210
|
+
account_id: Field.text({
|
|
211
|
+
label: "Provider Account ID",
|
|
212
|
+
required: true,
|
|
213
|
+
description: "User's ID in the provider's system"
|
|
214
|
+
}),
|
|
215
|
+
user_id: Field.lookup("sys_user", {
|
|
216
|
+
label: "User",
|
|
217
|
+
required: true,
|
|
218
|
+
description: "Link to user table"
|
|
219
|
+
}),
|
|
220
|
+
access_token: Field.textarea({
|
|
221
|
+
label: "Access Token",
|
|
222
|
+
required: false
|
|
223
|
+
}),
|
|
224
|
+
refresh_token: Field.textarea({
|
|
225
|
+
label: "Refresh Token",
|
|
226
|
+
required: false
|
|
227
|
+
}),
|
|
228
|
+
id_token: Field.textarea({
|
|
229
|
+
label: "ID Token",
|
|
230
|
+
required: false
|
|
231
|
+
}),
|
|
232
|
+
access_token_expires_at: Field.datetime({
|
|
233
|
+
label: "Access Token Expires At",
|
|
234
|
+
required: false
|
|
235
|
+
}),
|
|
236
|
+
refresh_token_expires_at: Field.datetime({
|
|
237
|
+
label: "Refresh Token Expires At",
|
|
238
|
+
required: false
|
|
239
|
+
}),
|
|
240
|
+
scope: Field.text({
|
|
241
|
+
label: "OAuth Scope",
|
|
242
|
+
required: false
|
|
243
|
+
}),
|
|
244
|
+
password: Field.text({
|
|
245
|
+
label: "Password Hash",
|
|
246
|
+
required: false,
|
|
247
|
+
description: "Hashed password for email/password provider"
|
|
248
|
+
})
|
|
249
|
+
},
|
|
250
|
+
indexes: [
|
|
251
|
+
{ fields: ["user_id"], unique: false },
|
|
252
|
+
{ fields: ["provider_id", "account_id"], unique: true }
|
|
253
|
+
],
|
|
254
|
+
enable: {
|
|
255
|
+
trackHistory: false,
|
|
256
|
+
searchable: false,
|
|
257
|
+
apiEnabled: true,
|
|
258
|
+
apiMethods: ["get", "list", "create", "update", "delete"],
|
|
259
|
+
trash: true,
|
|
260
|
+
mru: false
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
var SysVerification = ObjectSchema.create({
|
|
264
|
+
name: "sys_verification",
|
|
265
|
+
label: "Verification",
|
|
266
|
+
pluralLabel: "Verifications",
|
|
267
|
+
icon: "shield-check",
|
|
268
|
+
isSystem: true,
|
|
269
|
+
description: "Email and phone verification tokens",
|
|
270
|
+
titleFormat: "Verification for {identifier}",
|
|
271
|
+
compactLayout: ["identifier", "expires_at", "created_at"],
|
|
272
|
+
fields: {
|
|
273
|
+
id: Field.text({
|
|
274
|
+
label: "Verification ID",
|
|
275
|
+
required: true,
|
|
276
|
+
readonly: true
|
|
277
|
+
}),
|
|
278
|
+
created_at: Field.datetime({
|
|
279
|
+
label: "Created At",
|
|
280
|
+
defaultValue: "NOW()",
|
|
281
|
+
readonly: true
|
|
282
|
+
}),
|
|
283
|
+
updated_at: Field.datetime({
|
|
284
|
+
label: "Updated At",
|
|
285
|
+
defaultValue: "NOW()",
|
|
286
|
+
readonly: true
|
|
287
|
+
}),
|
|
288
|
+
value: Field.text({
|
|
289
|
+
label: "Verification Token",
|
|
290
|
+
required: true,
|
|
291
|
+
description: "Token or code for verification"
|
|
292
|
+
}),
|
|
293
|
+
expires_at: Field.datetime({
|
|
294
|
+
label: "Expires At",
|
|
295
|
+
required: true
|
|
296
|
+
}),
|
|
297
|
+
identifier: Field.text({
|
|
298
|
+
label: "Identifier",
|
|
299
|
+
required: true,
|
|
300
|
+
description: "Email address or phone number"
|
|
301
|
+
})
|
|
302
|
+
},
|
|
303
|
+
indexes: [
|
|
304
|
+
{ fields: ["value"], unique: true },
|
|
305
|
+
{ fields: ["identifier"], unique: false },
|
|
306
|
+
{ fields: ["expires_at"], unique: false }
|
|
307
|
+
],
|
|
308
|
+
enable: {
|
|
309
|
+
trackHistory: false,
|
|
310
|
+
searchable: false,
|
|
311
|
+
apiEnabled: true,
|
|
312
|
+
apiMethods: ["get", "create", "delete"],
|
|
313
|
+
trash: false,
|
|
314
|
+
mru: false
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
var SysOrganization = ObjectSchema.create({
|
|
318
|
+
name: "sys_organization",
|
|
319
|
+
label: "Organization",
|
|
320
|
+
pluralLabel: "Organizations",
|
|
321
|
+
icon: "building-2",
|
|
322
|
+
isSystem: true,
|
|
323
|
+
description: "Organizations for multi-tenant grouping",
|
|
324
|
+
displayNameField: "name",
|
|
325
|
+
titleFormat: "{name}",
|
|
326
|
+
compactLayout: ["name", "slug"],
|
|
327
|
+
fields: {
|
|
328
|
+
// ── Identity ─────────────────────────────────────────────────
|
|
329
|
+
name: Field.text({
|
|
330
|
+
label: "Name",
|
|
331
|
+
required: true,
|
|
332
|
+
searchable: true,
|
|
333
|
+
maxLength: 255,
|
|
334
|
+
group: "Identity"
|
|
335
|
+
}),
|
|
336
|
+
slug: Field.text({
|
|
337
|
+
label: "Slug",
|
|
338
|
+
required: false,
|
|
339
|
+
searchable: true,
|
|
340
|
+
maxLength: 255,
|
|
341
|
+
description: "URL-friendly identifier",
|
|
342
|
+
group: "Identity"
|
|
343
|
+
}),
|
|
344
|
+
// ── Branding ─────────────────────────────────────────────────
|
|
345
|
+
logo: Field.url({
|
|
346
|
+
label: "Logo",
|
|
347
|
+
required: false,
|
|
348
|
+
group: "Branding"
|
|
349
|
+
}),
|
|
350
|
+
// ── Configuration ────────────────────────────────────────────
|
|
351
|
+
metadata: Field.textarea({
|
|
352
|
+
label: "Metadata",
|
|
353
|
+
required: false,
|
|
354
|
+
description: "JSON-serialized organization metadata",
|
|
355
|
+
group: "Configuration"
|
|
356
|
+
}),
|
|
357
|
+
// ── System ───────────────────────────────────────────────────
|
|
358
|
+
id: Field.text({
|
|
359
|
+
label: "Organization ID",
|
|
360
|
+
required: true,
|
|
361
|
+
readonly: true,
|
|
362
|
+
group: "System"
|
|
363
|
+
}),
|
|
364
|
+
created_at: Field.datetime({
|
|
365
|
+
label: "Created At",
|
|
366
|
+
defaultValue: "NOW()",
|
|
367
|
+
readonly: true,
|
|
368
|
+
group: "System"
|
|
369
|
+
}),
|
|
370
|
+
updated_at: Field.datetime({
|
|
371
|
+
label: "Updated At",
|
|
372
|
+
defaultValue: "NOW()",
|
|
373
|
+
readonly: true,
|
|
374
|
+
group: "System"
|
|
375
|
+
})
|
|
376
|
+
},
|
|
377
|
+
indexes: [
|
|
378
|
+
{ fields: ["slug"], unique: true },
|
|
379
|
+
{ fields: ["name"] }
|
|
380
|
+
],
|
|
381
|
+
enable: {
|
|
382
|
+
trackHistory: true,
|
|
383
|
+
searchable: true,
|
|
384
|
+
apiEnabled: true,
|
|
385
|
+
apiMethods: ["get", "list", "create", "update", "delete"],
|
|
386
|
+
trash: true,
|
|
387
|
+
mru: true
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
var SysMember = ObjectSchema.create({
|
|
391
|
+
name: "sys_member",
|
|
392
|
+
label: "Member",
|
|
393
|
+
pluralLabel: "Members",
|
|
394
|
+
icon: "user-check",
|
|
395
|
+
isSystem: true,
|
|
396
|
+
description: "Organization membership records",
|
|
397
|
+
titleFormat: "{user_id} in {organization_id}",
|
|
398
|
+
compactLayout: ["user_id", "organization_id", "role"],
|
|
399
|
+
fields: {
|
|
400
|
+
id: Field.text({
|
|
401
|
+
label: "Member ID",
|
|
402
|
+
required: true,
|
|
403
|
+
readonly: true
|
|
404
|
+
}),
|
|
405
|
+
created_at: Field.datetime({
|
|
406
|
+
label: "Created At",
|
|
407
|
+
defaultValue: "NOW()",
|
|
408
|
+
readonly: true
|
|
409
|
+
}),
|
|
410
|
+
organization_id: Field.lookup("sys_organization", {
|
|
411
|
+
label: "Organization",
|
|
412
|
+
required: true
|
|
413
|
+
}),
|
|
414
|
+
user_id: Field.lookup("sys_user", {
|
|
415
|
+
label: "User",
|
|
416
|
+
required: true
|
|
417
|
+
}),
|
|
418
|
+
role: Field.text({
|
|
419
|
+
label: "Role",
|
|
420
|
+
required: false,
|
|
421
|
+
description: "Member role within the organization (e.g. admin, member)",
|
|
422
|
+
maxLength: 100
|
|
423
|
+
})
|
|
424
|
+
},
|
|
425
|
+
indexes: [
|
|
426
|
+
{ fields: ["organization_id", "user_id"], unique: true },
|
|
427
|
+
{ fields: ["user_id"] }
|
|
428
|
+
],
|
|
429
|
+
enable: {
|
|
430
|
+
trackHistory: true,
|
|
431
|
+
searchable: false,
|
|
432
|
+
apiEnabled: true,
|
|
433
|
+
apiMethods: ["get", "list", "create", "update", "delete"],
|
|
434
|
+
trash: false,
|
|
435
|
+
mru: false
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
var SysInvitation = ObjectSchema.create({
|
|
439
|
+
name: "sys_invitation",
|
|
440
|
+
label: "Invitation",
|
|
441
|
+
pluralLabel: "Invitations",
|
|
442
|
+
icon: "mail",
|
|
443
|
+
isSystem: true,
|
|
444
|
+
description: "Organization invitations for user onboarding",
|
|
445
|
+
titleFormat: "Invitation to {organization_id}",
|
|
446
|
+
compactLayout: ["email", "organization_id", "status"],
|
|
447
|
+
fields: {
|
|
448
|
+
id: Field.text({
|
|
449
|
+
label: "Invitation ID",
|
|
450
|
+
required: true,
|
|
451
|
+
readonly: true
|
|
452
|
+
}),
|
|
453
|
+
created_at: Field.datetime({
|
|
454
|
+
label: "Created At",
|
|
455
|
+
defaultValue: "NOW()",
|
|
456
|
+
readonly: true
|
|
457
|
+
}),
|
|
458
|
+
organization_id: Field.lookup("sys_organization", {
|
|
459
|
+
label: "Organization",
|
|
460
|
+
required: true
|
|
461
|
+
}),
|
|
462
|
+
email: Field.email({
|
|
463
|
+
label: "Email",
|
|
464
|
+
required: true,
|
|
465
|
+
description: "Email address of the invited user"
|
|
466
|
+
}),
|
|
467
|
+
role: Field.text({
|
|
468
|
+
label: "Role",
|
|
469
|
+
required: false,
|
|
470
|
+
maxLength: 100,
|
|
471
|
+
description: "Role to assign upon acceptance"
|
|
472
|
+
}),
|
|
473
|
+
status: Field.select(["pending", "accepted", "rejected", "expired", "canceled"], {
|
|
474
|
+
label: "Status",
|
|
475
|
+
required: true,
|
|
476
|
+
defaultValue: "pending"
|
|
477
|
+
}),
|
|
478
|
+
inviter_id: Field.lookup("sys_user", {
|
|
479
|
+
label: "Inviter",
|
|
480
|
+
required: true,
|
|
481
|
+
description: "User who sent the invitation"
|
|
482
|
+
}),
|
|
483
|
+
expires_at: Field.datetime({
|
|
484
|
+
label: "Expires At",
|
|
485
|
+
required: true
|
|
486
|
+
}),
|
|
487
|
+
team_id: Field.lookup("sys_team", {
|
|
488
|
+
label: "Team",
|
|
489
|
+
required: false,
|
|
490
|
+
description: "Optional team to assign upon acceptance"
|
|
491
|
+
})
|
|
492
|
+
},
|
|
493
|
+
indexes: [
|
|
494
|
+
{ fields: ["organization_id"] },
|
|
495
|
+
{ fields: ["email"] },
|
|
496
|
+
{ fields: ["expires_at"] }
|
|
497
|
+
],
|
|
498
|
+
enable: {
|
|
499
|
+
trackHistory: true,
|
|
500
|
+
searchable: false,
|
|
501
|
+
apiEnabled: true,
|
|
502
|
+
apiMethods: ["get", "list", "create", "update", "delete"],
|
|
503
|
+
trash: false,
|
|
504
|
+
mru: false
|
|
505
|
+
}
|
|
506
|
+
});
|
|
507
|
+
var SysTeam = ObjectSchema.create({
|
|
508
|
+
name: "sys_team",
|
|
509
|
+
label: "Team",
|
|
510
|
+
pluralLabel: "Teams",
|
|
511
|
+
icon: "users",
|
|
512
|
+
isSystem: true,
|
|
513
|
+
description: "Teams within organizations for fine-grained grouping",
|
|
514
|
+
displayNameField: "name",
|
|
515
|
+
titleFormat: "{name}",
|
|
516
|
+
compactLayout: ["name", "organization_id"],
|
|
517
|
+
fields: {
|
|
518
|
+
// ── Identity ─────────────────────────────────────────────────
|
|
519
|
+
name: Field.text({
|
|
520
|
+
label: "Name",
|
|
521
|
+
required: true,
|
|
522
|
+
searchable: true,
|
|
523
|
+
maxLength: 255,
|
|
524
|
+
group: "Identity"
|
|
525
|
+
}),
|
|
526
|
+
organization_id: Field.lookup("sys_organization", {
|
|
527
|
+
label: "Organization",
|
|
528
|
+
required: true,
|
|
529
|
+
description: "Parent organization for this team",
|
|
530
|
+
group: "Identity"
|
|
531
|
+
}),
|
|
532
|
+
// ── System ───────────────────────────────────────────────────
|
|
533
|
+
id: Field.text({
|
|
534
|
+
label: "Team ID",
|
|
535
|
+
required: true,
|
|
536
|
+
readonly: true,
|
|
537
|
+
group: "System"
|
|
538
|
+
}),
|
|
539
|
+
created_at: Field.datetime({
|
|
540
|
+
label: "Created At",
|
|
541
|
+
defaultValue: "NOW()",
|
|
542
|
+
readonly: true,
|
|
543
|
+
group: "System"
|
|
544
|
+
}),
|
|
545
|
+
updated_at: Field.datetime({
|
|
546
|
+
label: "Updated At",
|
|
547
|
+
defaultValue: "NOW()",
|
|
548
|
+
readonly: true,
|
|
549
|
+
group: "System"
|
|
550
|
+
})
|
|
551
|
+
},
|
|
552
|
+
indexes: [
|
|
553
|
+
{ fields: ["organization_id"] },
|
|
554
|
+
{ fields: ["name", "organization_id"], unique: true }
|
|
555
|
+
],
|
|
556
|
+
enable: {
|
|
557
|
+
trackHistory: true,
|
|
558
|
+
searchable: true,
|
|
559
|
+
apiEnabled: true,
|
|
560
|
+
apiMethods: ["get", "list", "create", "update", "delete"],
|
|
561
|
+
trash: true,
|
|
562
|
+
mru: false
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
var SysTeamMember = ObjectSchema.create({
|
|
566
|
+
name: "sys_team_member",
|
|
567
|
+
label: "Team Member",
|
|
568
|
+
pluralLabel: "Team Members",
|
|
569
|
+
icon: "user-plus",
|
|
570
|
+
isSystem: true,
|
|
571
|
+
description: "Team membership records linking users to teams",
|
|
572
|
+
titleFormat: "{user_id} in {team_id}",
|
|
573
|
+
compactLayout: ["user_id", "team_id", "created_at"],
|
|
574
|
+
fields: {
|
|
575
|
+
id: Field.text({
|
|
576
|
+
label: "Team Member ID",
|
|
577
|
+
required: true,
|
|
578
|
+
readonly: true
|
|
579
|
+
}),
|
|
580
|
+
created_at: Field.datetime({
|
|
581
|
+
label: "Created At",
|
|
582
|
+
defaultValue: "NOW()",
|
|
583
|
+
readonly: true
|
|
584
|
+
}),
|
|
585
|
+
team_id: Field.lookup("sys_team", {
|
|
586
|
+
label: "Team",
|
|
587
|
+
required: true
|
|
588
|
+
}),
|
|
589
|
+
user_id: Field.lookup("sys_user", {
|
|
590
|
+
label: "User",
|
|
591
|
+
required: true
|
|
592
|
+
})
|
|
593
|
+
},
|
|
594
|
+
indexes: [
|
|
595
|
+
{ fields: ["team_id", "user_id"], unique: true },
|
|
596
|
+
{ fields: ["user_id"] }
|
|
597
|
+
],
|
|
598
|
+
enable: {
|
|
599
|
+
trackHistory: true,
|
|
600
|
+
searchable: false,
|
|
601
|
+
apiEnabled: true,
|
|
602
|
+
apiMethods: ["get", "list", "create", "delete"],
|
|
603
|
+
trash: false,
|
|
604
|
+
mru: false
|
|
605
|
+
}
|
|
606
|
+
});
|
|
607
|
+
var SysApiKey = ObjectSchema.create({
|
|
608
|
+
name: "sys_api_key",
|
|
609
|
+
label: "API Key",
|
|
610
|
+
pluralLabel: "API Keys",
|
|
611
|
+
icon: "key-round",
|
|
612
|
+
isSystem: true,
|
|
613
|
+
description: "API keys for programmatic access",
|
|
614
|
+
displayNameField: "name",
|
|
615
|
+
titleFormat: "{name}",
|
|
616
|
+
compactLayout: ["name", "prefix", "user_id", "expires_at", "revoked"],
|
|
617
|
+
fields: {
|
|
618
|
+
// ── Identity ─────────────────────────────────────────────────
|
|
619
|
+
name: Field.text({
|
|
620
|
+
label: "Name",
|
|
621
|
+
required: true,
|
|
622
|
+
searchable: true,
|
|
623
|
+
maxLength: 255,
|
|
624
|
+
description: "Human-readable label for the API key",
|
|
625
|
+
group: "Identity"
|
|
626
|
+
}),
|
|
627
|
+
prefix: Field.text({
|
|
628
|
+
label: "Prefix",
|
|
629
|
+
required: false,
|
|
630
|
+
maxLength: 16,
|
|
631
|
+
description: 'Visible prefix for identifying the key (e.g., "osk_")',
|
|
632
|
+
group: "Identity"
|
|
633
|
+
}),
|
|
634
|
+
user_id: Field.lookup("sys_user", {
|
|
635
|
+
label: "Owner",
|
|
636
|
+
required: true,
|
|
637
|
+
description: "User who owns this API key",
|
|
638
|
+
group: "Identity"
|
|
639
|
+
}),
|
|
640
|
+
// ── Access ───────────────────────────────────────────────────
|
|
641
|
+
scopes: Field.textarea({
|
|
642
|
+
label: "Scopes",
|
|
643
|
+
required: false,
|
|
644
|
+
description: "JSON array of permission scopes",
|
|
645
|
+
group: "Access"
|
|
646
|
+
}),
|
|
647
|
+
// ── Lifecycle ────────────────────────────────────────────────
|
|
648
|
+
expires_at: Field.datetime({
|
|
649
|
+
label: "Expires At",
|
|
650
|
+
required: false,
|
|
651
|
+
group: "Lifecycle"
|
|
652
|
+
}),
|
|
653
|
+
last_used_at: Field.datetime({
|
|
654
|
+
label: "Last Used At",
|
|
655
|
+
required: false,
|
|
656
|
+
readonly: true,
|
|
657
|
+
description: "Automatically updated on each API call",
|
|
658
|
+
group: "Lifecycle"
|
|
659
|
+
}),
|
|
660
|
+
revoked: Field.boolean({
|
|
661
|
+
label: "Revoked",
|
|
662
|
+
defaultValue: false,
|
|
663
|
+
group: "Lifecycle"
|
|
664
|
+
}),
|
|
665
|
+
// ── Secret (hidden by default) ──────────────────────────────
|
|
666
|
+
key: Field.text({
|
|
667
|
+
label: "Hashed Key",
|
|
668
|
+
required: true,
|
|
669
|
+
hidden: true,
|
|
670
|
+
readonly: true,
|
|
671
|
+
description: "Hashed API key value \u2014 never exposed to clients",
|
|
672
|
+
group: "Secret"
|
|
673
|
+
}),
|
|
674
|
+
// ── System ───────────────────────────────────────────────────
|
|
675
|
+
id: Field.text({
|
|
676
|
+
label: "API Key ID",
|
|
677
|
+
required: true,
|
|
678
|
+
readonly: true,
|
|
679
|
+
group: "System"
|
|
680
|
+
}),
|
|
681
|
+
created_at: Field.datetime({
|
|
682
|
+
label: "Created At",
|
|
683
|
+
defaultValue: "NOW()",
|
|
684
|
+
readonly: true,
|
|
685
|
+
group: "System"
|
|
686
|
+
}),
|
|
687
|
+
updated_at: Field.datetime({
|
|
688
|
+
label: "Updated At",
|
|
689
|
+
defaultValue: "NOW()",
|
|
690
|
+
readonly: true,
|
|
691
|
+
group: "System"
|
|
692
|
+
})
|
|
693
|
+
},
|
|
694
|
+
indexes: [
|
|
695
|
+
{ fields: ["key"], unique: true },
|
|
696
|
+
{ fields: ["user_id"] },
|
|
697
|
+
{ fields: ["prefix"] },
|
|
698
|
+
{ fields: ["revoked"] }
|
|
699
|
+
],
|
|
700
|
+
enable: {
|
|
701
|
+
trackHistory: true,
|
|
702
|
+
searchable: false,
|
|
703
|
+
apiEnabled: true,
|
|
704
|
+
apiMethods: ["get", "list", "create", "update", "delete"],
|
|
705
|
+
trash: false,
|
|
706
|
+
mru: false
|
|
707
|
+
}
|
|
708
|
+
});
|
|
709
|
+
var SysTwoFactor = ObjectSchema.create({
|
|
710
|
+
name: "sys_two_factor",
|
|
711
|
+
label: "Two Factor",
|
|
712
|
+
pluralLabel: "Two Factor Credentials",
|
|
713
|
+
icon: "smartphone",
|
|
714
|
+
isSystem: true,
|
|
715
|
+
description: "Two-factor authentication credentials",
|
|
716
|
+
titleFormat: "Two-factor for {user_id}",
|
|
717
|
+
compactLayout: ["user_id", "created_at"],
|
|
718
|
+
fields: {
|
|
719
|
+
id: Field.text({
|
|
720
|
+
label: "Two Factor ID",
|
|
721
|
+
required: true,
|
|
722
|
+
readonly: true
|
|
723
|
+
}),
|
|
724
|
+
created_at: Field.datetime({
|
|
725
|
+
label: "Created At",
|
|
726
|
+
defaultValue: "NOW()",
|
|
727
|
+
readonly: true
|
|
728
|
+
}),
|
|
729
|
+
updated_at: Field.datetime({
|
|
730
|
+
label: "Updated At",
|
|
731
|
+
defaultValue: "NOW()",
|
|
732
|
+
readonly: true
|
|
733
|
+
}),
|
|
734
|
+
user_id: Field.lookup("sys_user", {
|
|
735
|
+
label: "User",
|
|
736
|
+
required: true
|
|
737
|
+
}),
|
|
738
|
+
secret: Field.text({
|
|
739
|
+
label: "Secret",
|
|
740
|
+
required: true,
|
|
741
|
+
description: "TOTP secret key"
|
|
742
|
+
}),
|
|
743
|
+
backup_codes: Field.textarea({
|
|
744
|
+
label: "Backup Codes",
|
|
745
|
+
required: false,
|
|
746
|
+
description: "JSON-serialized backup recovery codes"
|
|
747
|
+
})
|
|
748
|
+
},
|
|
749
|
+
indexes: [
|
|
750
|
+
{ fields: ["user_id"], unique: true }
|
|
751
|
+
],
|
|
752
|
+
enable: {
|
|
753
|
+
trackHistory: false,
|
|
754
|
+
searchable: false,
|
|
755
|
+
apiEnabled: true,
|
|
756
|
+
apiMethods: ["get", "create", "update", "delete"],
|
|
757
|
+
trash: false,
|
|
758
|
+
mru: false
|
|
759
|
+
}
|
|
760
|
+
});
|
|
761
|
+
var SysDeviceCode = ObjectSchema.create({
|
|
762
|
+
name: "sys_device_code",
|
|
763
|
+
label: "Device Code",
|
|
764
|
+
pluralLabel: "Device Codes",
|
|
765
|
+
icon: "key-round",
|
|
766
|
+
isSystem: true,
|
|
767
|
+
description: "OAuth 2.0 Device Authorization Grant (RFC 8628) pending requests",
|
|
768
|
+
titleFormat: "{user_code}",
|
|
769
|
+
compactLayout: ["user_code", "status", "client_id", "expires_at"],
|
|
770
|
+
fields: {
|
|
771
|
+
id: Field.text({
|
|
772
|
+
label: "Device Code ID",
|
|
773
|
+
required: true,
|
|
774
|
+
readonly: true
|
|
775
|
+
}),
|
|
776
|
+
created_at: Field.datetime({
|
|
777
|
+
label: "Created At",
|
|
778
|
+
defaultValue: "NOW()",
|
|
779
|
+
readonly: true
|
|
780
|
+
}),
|
|
781
|
+
updated_at: Field.datetime({
|
|
782
|
+
label: "Updated At",
|
|
783
|
+
defaultValue: "NOW()",
|
|
784
|
+
readonly: true
|
|
785
|
+
}),
|
|
786
|
+
/** High-entropy token returned to the device (CLI). Polled at /device/token. */
|
|
787
|
+
device_code: Field.text({
|
|
788
|
+
label: "Device Code",
|
|
789
|
+
required: true,
|
|
790
|
+
description: "High-entropy token returned to the polling device"
|
|
791
|
+
}),
|
|
792
|
+
/** Human-readable short code displayed to the user (e.g. ABCD-EFGH). */
|
|
793
|
+
user_code: Field.text({
|
|
794
|
+
label: "User Code",
|
|
795
|
+
required: true,
|
|
796
|
+
description: "Short user-facing code (e.g. ABCD-EFGH)"
|
|
797
|
+
}),
|
|
798
|
+
/** Owning user — populated when the request is approved. */
|
|
799
|
+
user_id: Field.lookup("sys_user", {
|
|
800
|
+
label: "User",
|
|
801
|
+
required: false,
|
|
802
|
+
description: "User who approved the device authorization"
|
|
803
|
+
}),
|
|
804
|
+
expires_at: Field.datetime({
|
|
805
|
+
label: "Expires At",
|
|
806
|
+
required: true,
|
|
807
|
+
description: "When the device & user codes are no longer valid"
|
|
808
|
+
}),
|
|
809
|
+
/** 'pending' | 'approved' | 'denied' */
|
|
810
|
+
status: Field.text({
|
|
811
|
+
label: "Status",
|
|
812
|
+
required: true,
|
|
813
|
+
description: "Current status: 'pending' | 'approved' | 'denied'"
|
|
814
|
+
}),
|
|
815
|
+
last_polled_at: Field.datetime({
|
|
816
|
+
label: "Last Polled At",
|
|
817
|
+
required: false,
|
|
818
|
+
description: "Timestamp of the most recent /device/token poll"
|
|
819
|
+
}),
|
|
820
|
+
polling_interval: Field.number({
|
|
821
|
+
label: "Polling Interval (ms)",
|
|
822
|
+
required: false,
|
|
823
|
+
description: "Server-recommended minimum polling interval, in ms"
|
|
824
|
+
}),
|
|
825
|
+
client_id: Field.text({
|
|
826
|
+
label: "Client ID",
|
|
827
|
+
required: false,
|
|
828
|
+
description: "OAuth client identifier of the requesting device"
|
|
829
|
+
}),
|
|
830
|
+
scope: Field.text({
|
|
831
|
+
label: "Scope",
|
|
832
|
+
required: false,
|
|
833
|
+
description: "Space-separated OAuth scopes requested by the device"
|
|
834
|
+
})
|
|
835
|
+
},
|
|
836
|
+
indexes: [
|
|
837
|
+
{ fields: ["device_code"], unique: true },
|
|
838
|
+
{ fields: ["user_code"], unique: true },
|
|
839
|
+
{ fields: ["status"], unique: false }
|
|
840
|
+
],
|
|
841
|
+
enable: {
|
|
842
|
+
trackHistory: false,
|
|
843
|
+
searchable: false,
|
|
844
|
+
apiEnabled: true,
|
|
845
|
+
apiMethods: ["get", "create", "update", "delete"],
|
|
846
|
+
trash: false,
|
|
847
|
+
mru: false
|
|
848
|
+
}
|
|
849
|
+
});
|
|
850
|
+
var SysUserPreference = ObjectSchema.create({
|
|
851
|
+
name: "sys_user_preference",
|
|
852
|
+
label: "User Preference",
|
|
853
|
+
pluralLabel: "User Preferences",
|
|
854
|
+
icon: "settings",
|
|
855
|
+
isSystem: true,
|
|
856
|
+
description: "Per-user key-value preferences (theme, locale, etc.)",
|
|
857
|
+
titleFormat: "{key}",
|
|
858
|
+
compactLayout: ["user_id", "key"],
|
|
859
|
+
fields: {
|
|
860
|
+
id: Field.text({
|
|
861
|
+
label: "Preference ID",
|
|
862
|
+
required: true,
|
|
863
|
+
readonly: true
|
|
864
|
+
}),
|
|
865
|
+
created_at: Field.datetime({
|
|
866
|
+
label: "Created At",
|
|
867
|
+
defaultValue: "NOW()",
|
|
868
|
+
readonly: true
|
|
869
|
+
}),
|
|
870
|
+
updated_at: Field.datetime({
|
|
871
|
+
label: "Updated At",
|
|
872
|
+
defaultValue: "NOW()",
|
|
873
|
+
readonly: true
|
|
874
|
+
}),
|
|
875
|
+
user_id: Field.lookup("sys_user", {
|
|
876
|
+
label: "User",
|
|
877
|
+
required: true,
|
|
878
|
+
description: "Owner user of this preference"
|
|
879
|
+
}),
|
|
880
|
+
key: Field.text({
|
|
881
|
+
label: "Key",
|
|
882
|
+
required: true,
|
|
883
|
+
maxLength: 255,
|
|
884
|
+
description: "Preference key (e.g., theme, locale, plugin.ai.auto_save)"
|
|
885
|
+
}),
|
|
886
|
+
value: Field.json({
|
|
887
|
+
label: "Value",
|
|
888
|
+
description: "Preference value (any JSON-serializable type)"
|
|
889
|
+
})
|
|
890
|
+
},
|
|
891
|
+
indexes: [
|
|
892
|
+
{ fields: ["user_id", "key"], unique: true },
|
|
893
|
+
{ fields: ["user_id"], unique: false }
|
|
894
|
+
],
|
|
895
|
+
enable: {
|
|
896
|
+
trackHistory: false,
|
|
897
|
+
searchable: false,
|
|
898
|
+
apiEnabled: true,
|
|
899
|
+
apiMethods: ["get", "list", "create", "update", "delete"],
|
|
900
|
+
trash: false,
|
|
901
|
+
mru: false
|
|
902
|
+
}
|
|
903
|
+
});
|
|
904
|
+
var SysOauthApplication = ObjectSchema.create({
|
|
905
|
+
name: "sys_oauth_application",
|
|
906
|
+
label: "OAuth Application",
|
|
907
|
+
pluralLabel: "OAuth Applications",
|
|
908
|
+
icon: "key-round",
|
|
909
|
+
isSystem: true,
|
|
910
|
+
description: "Registered OAuth/OIDC client applications",
|
|
911
|
+
displayNameField: "name",
|
|
912
|
+
titleFormat: "{name}",
|
|
913
|
+
compactLayout: ["name", "client_id", "type", "disabled"],
|
|
914
|
+
fields: {
|
|
915
|
+
// ── Identity ─────────────────────────────────────────────────
|
|
916
|
+
id: Field.text({
|
|
917
|
+
label: "ID",
|
|
918
|
+
required: true,
|
|
919
|
+
readonly: true,
|
|
920
|
+
group: "System"
|
|
921
|
+
}),
|
|
922
|
+
name: Field.text({
|
|
923
|
+
label: "Name",
|
|
924
|
+
required: false,
|
|
925
|
+
searchable: true,
|
|
926
|
+
maxLength: 255,
|
|
927
|
+
group: "Identity"
|
|
928
|
+
}),
|
|
929
|
+
icon: Field.url({
|
|
930
|
+
label: "Icon",
|
|
931
|
+
required: false,
|
|
932
|
+
description: "Logo URL shown on the consent screen",
|
|
933
|
+
group: "Identity"
|
|
934
|
+
}),
|
|
935
|
+
uri: Field.url({
|
|
936
|
+
label: "Home URI",
|
|
937
|
+
required: false,
|
|
938
|
+
description: "Public homepage of the registered client",
|
|
939
|
+
group: "Identity"
|
|
940
|
+
}),
|
|
941
|
+
contacts: Field.textarea({
|
|
942
|
+
label: "Contacts",
|
|
943
|
+
required: false,
|
|
944
|
+
description: "JSON-serialized list of contact email addresses",
|
|
945
|
+
group: "Identity"
|
|
946
|
+
}),
|
|
947
|
+
tos: Field.url({
|
|
948
|
+
label: "Terms of Service",
|
|
949
|
+
required: false,
|
|
950
|
+
group: "Identity"
|
|
951
|
+
}),
|
|
952
|
+
policy: Field.url({
|
|
953
|
+
label: "Privacy Policy",
|
|
954
|
+
required: false,
|
|
955
|
+
group: "Identity"
|
|
956
|
+
}),
|
|
957
|
+
metadata: Field.textarea({
|
|
958
|
+
label: "Metadata",
|
|
959
|
+
required: false,
|
|
960
|
+
description: "JSON-serialized application metadata",
|
|
961
|
+
group: "Identity"
|
|
962
|
+
}),
|
|
963
|
+
// ── OAuth Credentials ────────────────────────────────────────
|
|
964
|
+
client_id: Field.text({
|
|
965
|
+
label: "Client ID",
|
|
966
|
+
required: true,
|
|
967
|
+
readonly: true,
|
|
968
|
+
maxLength: 255,
|
|
969
|
+
description: "Public OAuth client identifier",
|
|
970
|
+
group: "Credentials"
|
|
971
|
+
}),
|
|
972
|
+
client_secret: Field.text({
|
|
973
|
+
label: "Client Secret",
|
|
974
|
+
required: false,
|
|
975
|
+
maxLength: 1024,
|
|
976
|
+
description: "OAuth client secret (hashed/encrypted at rest)",
|
|
977
|
+
group: "Credentials"
|
|
978
|
+
}),
|
|
979
|
+
redirect_uris: Field.textarea({
|
|
980
|
+
label: "Redirect URIs",
|
|
981
|
+
required: true,
|
|
982
|
+
description: "JSON-serialized list of allowed redirect URIs",
|
|
983
|
+
group: "Credentials"
|
|
984
|
+
}),
|
|
985
|
+
post_logout_redirect_uris: Field.textarea({
|
|
986
|
+
label: "Post-logout Redirect URIs",
|
|
987
|
+
required: false,
|
|
988
|
+
description: "JSON-serialized list of allowed post-logout redirect URIs",
|
|
989
|
+
group: "Credentials"
|
|
990
|
+
}),
|
|
991
|
+
type: Field.select(["web", "native", "user-agent-based", "public"], {
|
|
992
|
+
label: "Client Type",
|
|
993
|
+
required: false,
|
|
994
|
+
defaultValue: "web",
|
|
995
|
+
group: "Credentials"
|
|
996
|
+
}),
|
|
997
|
+
public: Field.boolean({
|
|
998
|
+
label: "Public Client",
|
|
999
|
+
required: false,
|
|
1000
|
+
description: "Marks the client as a public (non-confidential) OAuth client",
|
|
1001
|
+
group: "Credentials"
|
|
1002
|
+
}),
|
|
1003
|
+
require_pkce: Field.boolean({
|
|
1004
|
+
label: "Require PKCE",
|
|
1005
|
+
required: false,
|
|
1006
|
+
group: "Credentials"
|
|
1007
|
+
}),
|
|
1008
|
+
token_endpoint_auth_method: Field.text({
|
|
1009
|
+
label: "Token Endpoint Auth Method",
|
|
1010
|
+
required: false,
|
|
1011
|
+
maxLength: 64,
|
|
1012
|
+
description: "e.g. client_secret_basic, client_secret_post, none",
|
|
1013
|
+
group: "Credentials"
|
|
1014
|
+
}),
|
|
1015
|
+
grant_types: Field.textarea({
|
|
1016
|
+
label: "Grant Types",
|
|
1017
|
+
required: false,
|
|
1018
|
+
description: "JSON-serialized list of allowed grant types",
|
|
1019
|
+
group: "Credentials"
|
|
1020
|
+
}),
|
|
1021
|
+
response_types: Field.textarea({
|
|
1022
|
+
label: "Response Types",
|
|
1023
|
+
required: false,
|
|
1024
|
+
description: "JSON-serialized list of allowed response types",
|
|
1025
|
+
group: "Credentials"
|
|
1026
|
+
}),
|
|
1027
|
+
scopes: Field.textarea({
|
|
1028
|
+
label: "Allowed Scopes",
|
|
1029
|
+
required: false,
|
|
1030
|
+
description: "JSON-serialized list of scopes the client may request",
|
|
1031
|
+
group: "Credentials"
|
|
1032
|
+
}),
|
|
1033
|
+
subject_type: Field.text({
|
|
1034
|
+
label: "Subject Type",
|
|
1035
|
+
required: false,
|
|
1036
|
+
maxLength: 32,
|
|
1037
|
+
description: "OIDC subject type (e.g. public, pairwise)",
|
|
1038
|
+
group: "Credentials"
|
|
1039
|
+
}),
|
|
1040
|
+
// ── Behaviour flags ──────────────────────────────────────────
|
|
1041
|
+
disabled: Field.boolean({
|
|
1042
|
+
label: "Disabled",
|
|
1043
|
+
required: false,
|
|
1044
|
+
defaultValue: false,
|
|
1045
|
+
group: "Behaviour"
|
|
1046
|
+
}),
|
|
1047
|
+
skip_consent: Field.boolean({
|
|
1048
|
+
label: "Skip Consent",
|
|
1049
|
+
required: false,
|
|
1050
|
+
description: "Treat as a trusted client and bypass the consent screen",
|
|
1051
|
+
group: "Behaviour"
|
|
1052
|
+
}),
|
|
1053
|
+
enable_end_session: Field.boolean({
|
|
1054
|
+
label: "Enable End Session",
|
|
1055
|
+
required: false,
|
|
1056
|
+
description: "Allow the client to call the OIDC end-session endpoint",
|
|
1057
|
+
group: "Behaviour"
|
|
1058
|
+
}),
|
|
1059
|
+
// ── Software statement (RFC 7591 §2.3) ───────────────────────
|
|
1060
|
+
software_id: Field.text({
|
|
1061
|
+
label: "Software ID",
|
|
1062
|
+
required: false,
|
|
1063
|
+
maxLength: 255,
|
|
1064
|
+
group: "Software"
|
|
1065
|
+
}),
|
|
1066
|
+
software_version: Field.text({
|
|
1067
|
+
label: "Software Version",
|
|
1068
|
+
required: false,
|
|
1069
|
+
maxLength: 64,
|
|
1070
|
+
group: "Software"
|
|
1071
|
+
}),
|
|
1072
|
+
software_statement: Field.textarea({
|
|
1073
|
+
label: "Software Statement",
|
|
1074
|
+
required: false,
|
|
1075
|
+
description: "Signed JWT asserting the client metadata (RFC 7591 \xA72.3)",
|
|
1076
|
+
group: "Software"
|
|
1077
|
+
}),
|
|
1078
|
+
// ── Ownership / system ───────────────────────────────────────
|
|
1079
|
+
user_id: Field.lookup("sys_user", {
|
|
1080
|
+
label: "Owner User",
|
|
1081
|
+
required: false,
|
|
1082
|
+
description: "User who registered this application",
|
|
1083
|
+
group: "System"
|
|
1084
|
+
}),
|
|
1085
|
+
reference_id: Field.text({
|
|
1086
|
+
label: "Reference ID",
|
|
1087
|
+
required: false,
|
|
1088
|
+
maxLength: 255,
|
|
1089
|
+
description: "Caller-supplied correlation identifier",
|
|
1090
|
+
group: "System"
|
|
1091
|
+
}),
|
|
1092
|
+
created_at: Field.datetime({
|
|
1093
|
+
label: "Created At",
|
|
1094
|
+
defaultValue: "NOW()",
|
|
1095
|
+
readonly: true,
|
|
1096
|
+
group: "System"
|
|
1097
|
+
}),
|
|
1098
|
+
updated_at: Field.datetime({
|
|
1099
|
+
label: "Updated At",
|
|
1100
|
+
defaultValue: "NOW()",
|
|
1101
|
+
readonly: true,
|
|
1102
|
+
group: "System"
|
|
1103
|
+
})
|
|
1104
|
+
},
|
|
1105
|
+
indexes: [
|
|
1106
|
+
{ fields: ["client_id"], unique: true },
|
|
1107
|
+
{ fields: ["user_id"] },
|
|
1108
|
+
{ fields: ["reference_id"] }
|
|
1109
|
+
],
|
|
1110
|
+
enable: {
|
|
1111
|
+
trackHistory: true,
|
|
1112
|
+
searchable: true,
|
|
1113
|
+
apiEnabled: true,
|
|
1114
|
+
apiMethods: ["get", "list", "delete"],
|
|
1115
|
+
trash: false,
|
|
1116
|
+
mru: false
|
|
1117
|
+
}
|
|
1118
|
+
});
|
|
1119
|
+
var SysOauthAccessToken = ObjectSchema.create({
|
|
1120
|
+
name: "sys_oauth_access_token",
|
|
1121
|
+
label: "OAuth Access Token",
|
|
1122
|
+
pluralLabel: "OAuth Access Tokens",
|
|
1123
|
+
icon: "ticket",
|
|
1124
|
+
isSystem: true,
|
|
1125
|
+
description: "Opaque OAuth access tokens issued to client applications",
|
|
1126
|
+
compactLayout: ["client_id", "user_id", "expires_at"],
|
|
1127
|
+
fields: {
|
|
1128
|
+
id: Field.text({
|
|
1129
|
+
label: "ID",
|
|
1130
|
+
required: true,
|
|
1131
|
+
readonly: true
|
|
1132
|
+
}),
|
|
1133
|
+
token: Field.text({
|
|
1134
|
+
label: "Token",
|
|
1135
|
+
required: true,
|
|
1136
|
+
maxLength: 1024,
|
|
1137
|
+
description: "Opaque access token value"
|
|
1138
|
+
}),
|
|
1139
|
+
client_id: Field.text({
|
|
1140
|
+
label: "Client ID",
|
|
1141
|
+
required: true,
|
|
1142
|
+
description: "Foreign key to sys_oauth_application.client_id"
|
|
1143
|
+
}),
|
|
1144
|
+
session_id: Field.lookup("sys_session", {
|
|
1145
|
+
label: "Session",
|
|
1146
|
+
required: false,
|
|
1147
|
+
description: "Foreign key to sys_session.id"
|
|
1148
|
+
}),
|
|
1149
|
+
user_id: Field.lookup("sys_user", {
|
|
1150
|
+
label: "User",
|
|
1151
|
+
required: false,
|
|
1152
|
+
description: "Foreign key to sys_user.id"
|
|
1153
|
+
}),
|
|
1154
|
+
refresh_id: Field.lookup("sys_oauth_refresh_token", {
|
|
1155
|
+
label: "Refresh Token",
|
|
1156
|
+
required: false,
|
|
1157
|
+
description: "Foreign key to sys_oauth_refresh_token.id"
|
|
1158
|
+
}),
|
|
1159
|
+
reference_id: Field.text({
|
|
1160
|
+
label: "Reference ID",
|
|
1161
|
+
required: false,
|
|
1162
|
+
maxLength: 255,
|
|
1163
|
+
description: "Caller-supplied correlation identifier"
|
|
1164
|
+
}),
|
|
1165
|
+
scopes: Field.textarea({
|
|
1166
|
+
label: "Scopes",
|
|
1167
|
+
required: true,
|
|
1168
|
+
description: "JSON-serialized list of scopes granted to this token"
|
|
1169
|
+
}),
|
|
1170
|
+
expires_at: Field.datetime({
|
|
1171
|
+
label: "Expires At",
|
|
1172
|
+
required: true
|
|
1173
|
+
}),
|
|
1174
|
+
created_at: Field.datetime({
|
|
1175
|
+
label: "Created At",
|
|
1176
|
+
defaultValue: "NOW()",
|
|
1177
|
+
readonly: true
|
|
1178
|
+
})
|
|
1179
|
+
},
|
|
1180
|
+
indexes: [
|
|
1181
|
+
{ fields: ["token"], unique: true },
|
|
1182
|
+
{ fields: ["client_id"] },
|
|
1183
|
+
{ fields: ["session_id"] },
|
|
1184
|
+
{ fields: ["user_id"] },
|
|
1185
|
+
{ fields: ["refresh_id"] }
|
|
1186
|
+
],
|
|
1187
|
+
enable: {
|
|
1188
|
+
trackHistory: false,
|
|
1189
|
+
searchable: false,
|
|
1190
|
+
apiEnabled: false,
|
|
1191
|
+
apiMethods: [],
|
|
1192
|
+
trash: false,
|
|
1193
|
+
mru: false
|
|
1194
|
+
}
|
|
1195
|
+
});
|
|
1196
|
+
var SysOauthRefreshToken = ObjectSchema.create({
|
|
1197
|
+
name: "sys_oauth_refresh_token",
|
|
1198
|
+
label: "OAuth Refresh Token",
|
|
1199
|
+
pluralLabel: "OAuth Refresh Tokens",
|
|
1200
|
+
icon: "refresh-cw",
|
|
1201
|
+
isSystem: true,
|
|
1202
|
+
description: "Opaque OAuth refresh tokens (linked to a session)",
|
|
1203
|
+
compactLayout: ["client_id", "user_id", "expires_at"],
|
|
1204
|
+
fields: {
|
|
1205
|
+
id: Field.text({
|
|
1206
|
+
label: "ID",
|
|
1207
|
+
required: true,
|
|
1208
|
+
readonly: true
|
|
1209
|
+
}),
|
|
1210
|
+
token: Field.text({
|
|
1211
|
+
label: "Token",
|
|
1212
|
+
required: true,
|
|
1213
|
+
maxLength: 1024,
|
|
1214
|
+
description: "Opaque refresh token value"
|
|
1215
|
+
}),
|
|
1216
|
+
client_id: Field.text({
|
|
1217
|
+
label: "Client ID",
|
|
1218
|
+
required: true,
|
|
1219
|
+
description: "Foreign key to sys_oauth_application.client_id"
|
|
1220
|
+
}),
|
|
1221
|
+
session_id: Field.lookup("sys_session", {
|
|
1222
|
+
label: "Session",
|
|
1223
|
+
required: false,
|
|
1224
|
+
description: "Foreign key to sys_session.id"
|
|
1225
|
+
}),
|
|
1226
|
+
user_id: Field.lookup("sys_user", {
|
|
1227
|
+
label: "User",
|
|
1228
|
+
required: true,
|
|
1229
|
+
description: "Foreign key to sys_user.id"
|
|
1230
|
+
}),
|
|
1231
|
+
reference_id: Field.text({
|
|
1232
|
+
label: "Reference ID",
|
|
1233
|
+
required: false,
|
|
1234
|
+
maxLength: 255,
|
|
1235
|
+
description: "Caller-supplied correlation identifier"
|
|
1236
|
+
}),
|
|
1237
|
+
scopes: Field.textarea({
|
|
1238
|
+
label: "Scopes",
|
|
1239
|
+
required: true,
|
|
1240
|
+
description: "JSON-serialized list of scopes granted to this token"
|
|
1241
|
+
}),
|
|
1242
|
+
expires_at: Field.datetime({
|
|
1243
|
+
label: "Expires At",
|
|
1244
|
+
required: true
|
|
1245
|
+
}),
|
|
1246
|
+
created_at: Field.datetime({
|
|
1247
|
+
label: "Created At",
|
|
1248
|
+
defaultValue: "NOW()",
|
|
1249
|
+
readonly: true
|
|
1250
|
+
}),
|
|
1251
|
+
revoked: Field.datetime({
|
|
1252
|
+
label: "Revoked At",
|
|
1253
|
+
required: false,
|
|
1254
|
+
description: "Timestamp at which this refresh token was revoked"
|
|
1255
|
+
}),
|
|
1256
|
+
auth_time: Field.datetime({
|
|
1257
|
+
label: "Auth Time",
|
|
1258
|
+
required: false,
|
|
1259
|
+
description: "When the user originally authenticated for this token chain"
|
|
1260
|
+
})
|
|
1261
|
+
},
|
|
1262
|
+
indexes: [
|
|
1263
|
+
{ fields: ["token"], unique: true },
|
|
1264
|
+
{ fields: ["client_id"] },
|
|
1265
|
+
{ fields: ["session_id"] },
|
|
1266
|
+
{ fields: ["user_id"] }
|
|
1267
|
+
],
|
|
1268
|
+
enable: {
|
|
1269
|
+
trackHistory: false,
|
|
1270
|
+
searchable: false,
|
|
1271
|
+
apiEnabled: false,
|
|
1272
|
+
apiMethods: [],
|
|
1273
|
+
trash: false,
|
|
1274
|
+
mru: false
|
|
1275
|
+
}
|
|
1276
|
+
});
|
|
1277
|
+
var SysOauthConsent = ObjectSchema.create({
|
|
1278
|
+
name: "sys_oauth_consent",
|
|
1279
|
+
label: "OAuth Consent",
|
|
1280
|
+
pluralLabel: "OAuth Consents",
|
|
1281
|
+
icon: "shield-check",
|
|
1282
|
+
isSystem: true,
|
|
1283
|
+
description: "User consent records for OAuth client applications",
|
|
1284
|
+
compactLayout: ["client_id", "user_id", "scopes"],
|
|
1285
|
+
fields: {
|
|
1286
|
+
id: Field.text({
|
|
1287
|
+
label: "ID",
|
|
1288
|
+
required: true,
|
|
1289
|
+
readonly: true
|
|
1290
|
+
}),
|
|
1291
|
+
client_id: Field.text({
|
|
1292
|
+
label: "Client ID",
|
|
1293
|
+
required: true,
|
|
1294
|
+
description: "Foreign key to sys_oauth_application.client_id"
|
|
1295
|
+
}),
|
|
1296
|
+
user_id: Field.lookup("sys_user", {
|
|
1297
|
+
label: "User",
|
|
1298
|
+
required: false,
|
|
1299
|
+
description: "Foreign key to sys_user.id"
|
|
1300
|
+
}),
|
|
1301
|
+
reference_id: Field.text({
|
|
1302
|
+
label: "Reference ID",
|
|
1303
|
+
required: false,
|
|
1304
|
+
maxLength: 255,
|
|
1305
|
+
description: "Caller-supplied correlation identifier"
|
|
1306
|
+
}),
|
|
1307
|
+
scopes: Field.textarea({
|
|
1308
|
+
label: "Scopes",
|
|
1309
|
+
required: true,
|
|
1310
|
+
description: "JSON-serialized list of scopes the user consented to"
|
|
1311
|
+
}),
|
|
1312
|
+
created_at: Field.datetime({
|
|
1313
|
+
label: "Created At",
|
|
1314
|
+
defaultValue: "NOW()",
|
|
1315
|
+
readonly: true
|
|
1316
|
+
}),
|
|
1317
|
+
updated_at: Field.datetime({
|
|
1318
|
+
label: "Updated At",
|
|
1319
|
+
defaultValue: "NOW()",
|
|
1320
|
+
readonly: true
|
|
1321
|
+
})
|
|
1322
|
+
},
|
|
1323
|
+
indexes: [
|
|
1324
|
+
{ fields: ["client_id"] },
|
|
1325
|
+
{ fields: ["user_id"] }
|
|
1326
|
+
],
|
|
1327
|
+
enable: {
|
|
1328
|
+
trackHistory: false,
|
|
1329
|
+
searchable: false,
|
|
1330
|
+
apiEnabled: false,
|
|
1331
|
+
apiMethods: [],
|
|
1332
|
+
trash: false,
|
|
1333
|
+
mru: false
|
|
1334
|
+
}
|
|
1335
|
+
});
|
|
1336
|
+
var SysJwks = ObjectSchema.create({
|
|
1337
|
+
name: "sys_jwks",
|
|
1338
|
+
label: "JWKS Key",
|
|
1339
|
+
pluralLabel: "JWKS Keys",
|
|
1340
|
+
icon: "key",
|
|
1341
|
+
isSystem: true,
|
|
1342
|
+
description: "Asymmetric key pairs used to sign and verify issued JWTs",
|
|
1343
|
+
compactLayout: ["id", "created_at", "expires_at"],
|
|
1344
|
+
fields: {
|
|
1345
|
+
id: Field.text({
|
|
1346
|
+
label: "Key ID",
|
|
1347
|
+
required: true,
|
|
1348
|
+
readonly: true,
|
|
1349
|
+
description: "JWK `kid` value"
|
|
1350
|
+
}),
|
|
1351
|
+
public_key: Field.textarea({
|
|
1352
|
+
label: "Public Key",
|
|
1353
|
+
required: true,
|
|
1354
|
+
description: "JSON-serialized JWK public key"
|
|
1355
|
+
}),
|
|
1356
|
+
private_key: Field.textarea({
|
|
1357
|
+
label: "Private Key",
|
|
1358
|
+
required: true,
|
|
1359
|
+
description: "JSON-serialized JWK private key (encrypted at rest)"
|
|
1360
|
+
}),
|
|
1361
|
+
created_at: Field.datetime({
|
|
1362
|
+
label: "Created At",
|
|
1363
|
+
required: true,
|
|
1364
|
+
defaultValue: "NOW()",
|
|
1365
|
+
readonly: true
|
|
1366
|
+
}),
|
|
1367
|
+
expires_at: Field.datetime({
|
|
1368
|
+
label: "Expires At",
|
|
1369
|
+
required: false,
|
|
1370
|
+
description: "When the key may no longer be used to verify tokens"
|
|
1371
|
+
})
|
|
1372
|
+
},
|
|
1373
|
+
enable: {
|
|
1374
|
+
trackHistory: false,
|
|
1375
|
+
searchable: false,
|
|
1376
|
+
apiEnabled: false,
|
|
1377
|
+
apiMethods: [],
|
|
1378
|
+
trash: false,
|
|
1379
|
+
mru: false
|
|
1380
|
+
}
|
|
1381
|
+
});
|
|
1382
|
+
|
|
1383
|
+
export { SysAccount, SysApiKey, SysDeviceCode, SysInvitation, SysJwks, SysMember, SysOauthAccessToken, SysOauthApplication, SysOauthConsent, SysOauthRefreshToken, SysOrganization, SysSession, SysTeam, SysTeamMember, SysTwoFactor, SysUser, SysUserPreference, SysVerification };
|
|
1384
|
+
//# sourceMappingURL=index.mjs.map
|
|
1385
|
+
//# sourceMappingURL=index.mjs.map
|