Releases: objectstack-ai/framework
Releases · objectstack-ai/framework
Release list
objectstack-vscode@14.3.0
objectstack-vscode@14.3.0
create-objectstack@14.3.0
create-objectstack@14.3.0
@objectstack/verify@14.3.0
Patch Changes
- Updated dependencies [2a71f48]
- Updated dependencies [02f6af4]
- Updated dependencies [8f0b9df]
- Updated dependencies [ff648ad]
- Updated dependencies [c1064f1]
- Updated dependencies [bea4b92]
- @objectstack/plugin-auth@14.3.0
- @objectstack/rest@14.3.0
- @objectstack/spec@14.3.0
- @objectstack/plugin-security@14.3.0
- @objectstack/objectql@14.3.0
- @objectstack/service-settings@14.3.0
- @objectstack/runtime@14.3.0
- @objectstack/plugin-sharing@14.3.0
- @objectstack/core@14.3.0
- @objectstack/driver-sqlite-wasm@14.3.0
- @objectstack/plugin-hono-server@14.3.0
- @objectstack/service-analytics@14.3.0
- @objectstack/service-automation@14.3.0
- @objectstack/service-datasource@14.3.0
@objectstack/types@14.3.0
@objectstack/trigger-schedule@14.3.0
@objectstack/trigger-record-change@14.3.0
@objectstack/trigger-api@14.3.0
@objectstack/studio@14.3.0
@objectstack/spec@14.3.0
Minor Changes
-
2a71f48: feat(auth): admin direct user management, phone sign-in, and identity bulk import (#2766, re-scoped #2758)
sys_useris managed by better-auth and its generic CRUD is suppressed, so
until now the only way to add a teammate was the email-dependent invite flow.
This ships three staged capabilities:- Admin direct user management —
POST /api/v1/auth/admin/create-user
and a wrappedPOST /api/v1/auth/admin/set-user-password(ADR-0068
platform-admin gate; better-auth pipeline so credentials are real). Optional
generated temporary password (returned once, never persisted or logged) and
a newsys_user.must_change_passwordflag enforced through the ADR-0069
authGate (403 PASSWORD_EXPIREDuntil the user changes it). New
create_useraction and upgradedset_user_passwordaction on the Users
list — pure schema, no frontend changes. - Phone sign-in (opt-in
auth.plugins.phoneNumber) — better-auth
phoneNumber plugin, phone+password only (POST /sign-in/phone-number);
OTP flows stay off until SMS infrastructure exists. Adds
sys_user.phone_number(unique) /phone_number_verified. Phone-only
accounts get an undeliverable placeholder email
(u-<random>@placeholder.invalid, never derived from the phone number);
all auth mail callbacks refuse placeholder recipients. - Identity bulk import —
POST /api/v1/auth/admin/import-usersaccepts
the same payloads as the generic import routes (rows/csv/xlsx, dryRun,
upsert by email or phone) but writes every row through better-auth.
Password policies:invite(reset-link email per created user; requires an
EmailService) andtemporary(per-row one-time passwords + forced change).
Sync only, ≤500 rows per request; no undo; upsert updates touch profile
fields only and can never reset an existing user's password.
prepareImportRequestand the CSV/xlsx parsers moved from rest-server.ts
to an exportedimport-prepare.tsmodule (behavior unchanged).
- Admin direct user management —
-
02f6af4: ADR-0090 follow-through wave: enforce book audience at the read layer; finish the D2/D3 cleanup the P1 rename missed.
- rest:
/meta/book,/meta/doc, and/meta/book/:name/treenow ENFORCE
the ADR-0046 §6.7 audience model (ADR-0049 — no unenforced security
properties): anonymous callers see onlypublicbooks/docs;
{ permissionSet }-gated books require the caller to hold the named set;
a doc's effective audience is the union over the books that CLAIM it
(unclaimed docs default toorg; orphan rendering never inheritspublic).
Gated evaluation fails CLOSED when holdings cannot be resolved.doc/book
single-item reads bypass the shared meta cache (per-caller gate vs shared ETag). - spec: new pure helpers powering that gate —
audienceAllows,
resolveDocAudiences,docAudienceAllows,resolveBookClaimedDocs
(+AudienceCaller/AudienceBooktypes). BREAKING but ships as aminor
per the launch-window convention (pre-1.0 semantics — breaking changes do
not burn a major version number while the whole stack is in lockstep):
METADATA_FORM_REGISTRYkeysrole/profileare gone —positionis the
registered form (thepositiontype had LOST its form layout in the P1
rename);EnvironmentArtifactMetadataSchemadeclarespositionsinstead of
retiredroles/profiles. - plugin-security: the
securityservice exposes
resolvePermissionSetNames(ctx)— the same resolution as data-plane
enforcement, for the docs gate. - metadata: artifact ingestion maps
positions → 'position'(the stale
roles → 'role'mapping matched nothing since the P1 rename, silently
dropping compiled positions from metadata registration). - lint: books join the D3 role-word scan (their
audienceis a
permission-model reference now), and a new advisory rule
security-book-audience-unknown-setflags a{ permissionSet }audience
naming a set the stack does not declare (runtime fails closed — the typo
cost is "nobody can read the book", so say it at author time). - platform-objects: metadata-form translations regain
position(all four
locales) and drop the retiredrole/profilegroups, with a vocabulary
regression test.
- rest:
-
c1064f1: feat(messaging/auth): SMS infrastructure + phone-number OTP first-login/reset (#2780)
#2766 shipped phone+password sign-in but no OTP — the platform had no SMS
delivery capability. This adds the missing infrastructure end to end:- New
@objectstack/plugin-sms—ISmsService/ISmsTransportcontracts
(spec) with Aliyun SMS (ACS3-HMAC-SHA256, template-based) and Twilio
transports plus a dev log fallback. Configured through the newsms
settings namespace (live provider rebind, encrypted secrets, send-test
action;OS_SMS_*env keys win at the resolver). Deliberately NO message
persistence and NO body logging — SMS bodies carry OTP codes. - Messaging
smschannel — registered at kernel:ready when ansms
service is present;notify(channels:['sms'])resolves
sys_user.phone_number, renders(topic,'sms',locale)templates, and
inherits outbox retry/dead-letter. - Phone OTP flows open — the phoneNumber plugin's
sendOTP/
sendPasswordResetOTPnow deliver via SMS, enabling
/phone-number/send-otp+/verify(OTP sign-in/verification) and
/phone-number/request-password-reset+/reset-password(self-service
reset). Without a deliverable SMS service they keep failing loudly
(NOT_SUPPORTED);features.phoneNumberOtpadvertises real availability.
Shipped with the abuse hardening: explicitallowedAttempts: 3, always-on
per-number cooldown (60s) + rolling-hour cap (5, secondaryStorage-shared
across nodes),/phone-number/*in the settings-bound per-IP rate-limit
rules, and OTP codes never reach logs or error messages. - Import SMS invites —
/admin/import-users'sinvitepolicy now
supports phone-only rows: a credential-free invitation SMS points the
employee at phone-OTP first sign-in followed by self-set password; mixed
files validate the reachable channel per row.
- New