@oimlsmart/platform-server 0.1.7 → 0.1.9

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.
@@ -0,0 +1,45 @@
1
+ -- Migration 0022 — multiple emails per account (TODO.identity-features/01):
2
+ -- the account gains a primary + additional addresses, each verified
3
+ -- independently, the sign-in and the recovery paths resolving by ANY
4
+ -- verified one.
5
+ --
6
+ -- The model:
7
+ -- - the PRIMARY address stays users.email (+ users.email_verified_at):
8
+ -- the OIDC `email` claim never changes shape, every existing reader
9
+ -- (the claims, the registry, the audit chain) is undisturbed, and the
10
+ -- claims keep carrying the primary on a switch;
11
+ -- - account_emails carries the ADDITIONAL addresses only — one row per
12
+ -- (account, address), verified_at NULL until the per-address ceremony
13
+ -- proves the mailbox. An address is globally unique across the estate
14
+ -- of addresses: the unique index keys it here, and the store's writes
15
+ -- check BOTH tables (an additional on account A blocks the address as
16
+ -- a primary or an additional anywhere else);
17
+ -- - the "primary" attribute is represented by WHERE the address lives
18
+ -- (the users row vs account_emails), never a flag to keep in sync —
19
+ -- the store's setPrimaryAccountEmail swaps the two residences with
20
+ -- their verification stamps;
21
+ -- - email_change_tokens gains `kind`: 'change' (the pre-0022 primary
22
+ -- replacement — the default, so existing rows read honestly) and
23
+ -- 'add' (the per-address verification of an account_emails row; the
24
+ -- row lands unverified at the request and the token's completion
25
+ -- stamps verified_at). The same one-time, 24 h, atomically-consumed
26
+ -- doctrine carries both.
27
+ -- schema.sql carries the same end state for fresh databases —
28
+ -- test/migrations.test.ts pins the UNION of every migration to
29
+ -- schema.sql's CREATE set.
30
+
31
+ CREATE TABLE IF NOT EXISTS account_emails (
32
+ user_id TEXT NOT NULL REFERENCES users(id),
33
+ email TEXT NOT NULL,
34
+ verified_at TEXT,
35
+ added_by TEXT,
36
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
37
+ PRIMARY KEY (user_id, email)
38
+ );
39
+ -- An address names at most ONE account across the estate (the sign-in
40
+ -- and recovery resolutions depend on it); the users.email UNIQUE covers
41
+ -- the primaries, this index the additionals, and the store's writes
42
+ -- check across both.
43
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_account_emails_email ON account_emails (email);
44
+
45
+ ALTER TABLE email_change_tokens ADD COLUMN kind TEXT NOT NULL DEFAULT 'change';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oimlsmart/platform-server",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "The OIML SMART platform server kernel: the store seam (ServerStore + the D1 and SQLite implementations), the canonical D1 migration set both deployments apply, the instance profile, the mailer, the RBAC map, the OIDC/OAuth client cones, and the shared role/permission vocabulary. Consumed by the smart monorepo (browser/) and the identity service.",
5
5
  "type": "module",
6
6
  "repository": {