@objectstack/platform-objects 13.0.0 → 14.3.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.
@@ -103,6 +103,62 @@ var SysUser = data.ObjectSchema.create({
103
103
  successMessage: "Account unlocked",
104
104
  refreshAfter: true
105
105
  },
106
+ {
107
+ // #2766 V1 — a platform admin can add a login-capable teammate without
108
+ // the email-dependent invite flow. Hits the plugin-auth wrapper route
109
+ // (NOT better-auth's stock /admin/create-user): the wrapper runs the
110
+ // ADR-0068 admin gate, drives the better-auth pipeline (scrypt hash +
111
+ // credential sys_account), stamps must_change_password, and — when
112
+ // "Generate temporary password" is picked — returns the password ONCE
113
+ // in the response for the result dialog. It is never persisted or logged.
114
+ name: "create_user",
115
+ label: "Create User",
116
+ icon: "user-plus",
117
+ variant: "secondary",
118
+ locations: ["list_toolbar"],
119
+ type: "api",
120
+ target: "/api/v1/auth/admin/create-user",
121
+ visible: "features.admin == true",
122
+ successMessage: "User created",
123
+ refreshAfter: true,
124
+ params: [
125
+ // The endpoint requires email OR phone (phone-only users get a
126
+ // placeholder address; requires auth.plugins.phoneNumber).
127
+ { field: "email", required: false },
128
+ {
129
+ name: "phoneNumber",
130
+ label: "Phone Number",
131
+ type: "text",
132
+ required: false,
133
+ helpText: "Sign-in phone number (E.164, e.g. +8613800000000). Required when no email is given."
134
+ },
135
+ { field: "name", required: false },
136
+ {
137
+ name: "generatePassword",
138
+ label: "Generate Temporary Password",
139
+ type: "boolean",
140
+ required: false,
141
+ defaultValue: true
142
+ },
143
+ { name: "password", label: "Password (leave empty to generate)", type: "text", required: false },
144
+ {
145
+ name: "mustChangePassword",
146
+ label: "Require Password Change On First Login",
147
+ type: "boolean",
148
+ required: false,
149
+ defaultValue: true
150
+ }
151
+ ],
152
+ resultDialog: {
153
+ title: "User Created",
154
+ description: "Copy the temporary password now \u2014 it is shown only once and never stored.",
155
+ acknowledge: "I have saved this password",
156
+ fields: [
157
+ { path: "user.email", label: "Email", format: "text" },
158
+ { path: "temporaryPassword", label: "Temporary Password", format: "secret" }
159
+ ]
160
+ }
161
+ },
106
162
  {
107
163
  name: "set_user_password",
108
164
  label: "Set Password",
@@ -110,13 +166,40 @@ var SysUser = data.ObjectSchema.create({
110
166
  variant: "secondary",
111
167
  locations: ["list_item"],
112
168
  type: "api",
169
+ // #2766 V1 — same path as better-auth's stock route, but served by the
170
+ // plugin-auth wrapper registered ahead of the catch-all: it accepts the
171
+ // ADR-0068 platform-admin signals (the stock handler only honors the
172
+ // legacy role scalar), can mint a temporary password, and stamps
173
+ // must_change_password.
113
174
  target: "/api/v1/auth/admin/set-user-password",
114
175
  recordIdParam: "userId",
115
176
  successMessage: "Password updated",
116
177
  refreshAfter: false,
117
178
  params: [
118
- { name: "newPassword", label: "New Password", type: "text", required: true }
119
- ]
179
+ {
180
+ name: "generatePassword",
181
+ label: "Generate Temporary Password",
182
+ type: "boolean",
183
+ required: false,
184
+ defaultValue: false
185
+ },
186
+ { name: "newPassword", label: "New Password (leave empty to generate)", type: "text", required: false },
187
+ {
188
+ name: "mustChangePassword",
189
+ label: "Require Password Change On Next Login",
190
+ type: "boolean",
191
+ required: false,
192
+ defaultValue: true
193
+ }
194
+ ],
195
+ resultDialog: {
196
+ title: "Password Updated",
197
+ description: "If a temporary password was generated, copy it now \u2014 it is shown only once and never stored.",
198
+ acknowledge: "Done",
199
+ fields: [
200
+ { path: "temporaryPassword", label: "Temporary Password", format: "secret" }
201
+ ]
202
+ }
120
203
  },
121
204
  {
122
205
  name: "set_user_role",
@@ -435,6 +518,37 @@ var SysUser = data.ObjectSchema.create({
435
518
  group: "Admin",
436
519
  description: "Timestamp of the last password change. Backs password_expiry_days; system-managed."
437
520
  }),
521
+ // #2766 V1.5 — phone-number sign-in identifier (better-auth phoneNumber
522
+ // plugin, mapped via buildPhoneNumberPluginSchema). Unique when present;
523
+ // null for email-only accounts. Written through better-auth, not CRUD.
524
+ phone_number: data.Field.text({
525
+ label: "Phone Number",
526
+ required: false,
527
+ readonly: true,
528
+ searchable: true,
529
+ maxLength: 32,
530
+ group: "Account",
531
+ description: "Sign-in phone number (E.164 recommended). Unique per user; managed by better-auth when the phoneNumber plugin is enabled."
532
+ }),
533
+ phone_number_verified: data.Field.boolean({
534
+ label: "Phone Verified",
535
+ defaultValue: false,
536
+ readonly: true,
537
+ group: "Account",
538
+ description: "Whether the phone number has been verified (OTP verification requires SMS infrastructure; false until that ships). System-managed."
539
+ }),
540
+ // #2766 V1 — admin-issued "must change password on next sign-in" flag.
541
+ // Set by the /admin/create-user and /admin/set-user-password routes when
542
+ // a temporary password is issued; enforced through the ADR-0069 authGate
543
+ // (surfaces as PASSWORD_EXPIRED); cleared by stampPasswordChangedAt once
544
+ // the user completes a password change.
545
+ must_change_password: data.Field.boolean({
546
+ label: "Must Change Password",
547
+ defaultValue: false,
548
+ readonly: true,
549
+ group: "Admin",
550
+ description: "When true, the user is blocked (403 PASSWORD_EXPIRED) until they change their password. Stamped by the admin user-management routes; system-managed."
551
+ }),
438
552
  // ADR-0069 D3 — when enforced MFA first applied to this user; starts the
439
553
  // grace clock. Stamped lazily at session validation; system-managed.
440
554
  mfa_required_at: data.Field.datetime({
@@ -532,7 +646,10 @@ var SysUser = data.ObjectSchema.create({
532
646
  },
533
647
  indexes: [
534
648
  { fields: ["email"], unique: true },
535
- { fields: ["created_at"], unique: false }
649
+ { fields: ["created_at"], unique: false },
650
+ // #2766 V1.5 — phone sign-in identifier; unique when present (null for
651
+ // email-only accounts), also the upsert match key for identity import.
652
+ { fields: ["phone_number"], unique: true }
536
653
  ],
537
654
  enable: {
538
655
  trackHistory: true,