api: pair the mobile app with device tokens
MB1 (spec 13). Decision 0005: our own Android/iPhone app, Expo in the mobile repo, user portal only, no push in v1. - mobile_devices (migration 0013): one-time pairing codes from My settings (QR or server + code, 10 minutes), traded by the app for an spm_ device token that acts as its user and never as an admin - POST /api/me/mobile-devices/pair (web session only), POST /api/mobile/pair, GET/DELETE /api/me/mobile-devices - signing out everywhere (password change or reset, disabling) removes paired phones too - My settings: Mobile app section with the QR code and paired phones - mobile/ (its own repo) ignored here
This commit is contained in:
1 parent
adb6d52ddf
commit
0cdac0bcdc
26 files changed
+5340
-18
No files matched your search
@@ -0,0 +1,19 @@
|
||||
CREATE TABLE "mobile_devices" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"user_id" uuid NOT NULL,
|
||||
"name" text,
|
||||
"platform" text,
|
||||
"token_prefix" text,
|
||||
"token_hash" text,
|
||||
"pair_code_hash" text,
|
||||
"pair_expires_at" timestamp with time zone,
|
||||
"last_used_at" timestamp with time zone,
|
||||
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
|
||||
CONSTRAINT "mobile_devices_tokenHash_unique" UNIQUE("token_hash"),
|
||||
CONSTRAINT "mobile_devices_pairCodeHash_unique" UNIQUE("pair_code_hash"),
|
||||
CONSTRAINT "mobile_devices_platform_check" CHECK ("mobile_devices"."platform" in ('android', 'ios'))
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "mobile_devices" ADD CONSTRAINT "mobile_devices_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "mobile_devices_user_id_index" ON "mobile_devices" USING btree ("user_id");
|
||||
File diff suppressed because it is too large.
Load diff
@@ -92,6 +92,13 @@
|
||||
"when": 1792951905226,
|
||||
"tag": "0012_sso",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 13,
|
||||
"version": "7",
|
||||
"when": 1793052019332,
|
||||
"tag": "0013_mobile_devices",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -134,6 +134,29 @@ export const apiTokens = pgTable('api_tokens', {
|
||||
...timestamps,
|
||||
});
|
||||
|
||||
/** Paired phones (13 §3): a row waits with a pairing code, then holds the device token. */
|
||||
export const mobileDevices = pgTable(
|
||||
'mobile_devices',
|
||||
{
|
||||
id: id(),
|
||||
userId: uuid()
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: 'cascade' }),
|
||||
name: text(),
|
||||
platform: text(),
|
||||
tokenPrefix: text(),
|
||||
tokenHash: text().unique(),
|
||||
pairCodeHash: text().unique(),
|
||||
pairExpiresAt: tstz(),
|
||||
lastUsedAt: tstz(),
|
||||
...timestamps,
|
||||
},
|
||||
(t) => [
|
||||
index().on(t.userId),
|
||||
check('mobile_devices_platform_check', sql`${t.platform} in ('android', 'ios')`),
|
||||
],
|
||||
);
|
||||
|
||||
// ───────────── extensions ─────────────
|
||||
export const outboundClass = pgEnum('outbound_class', [
|
||||
'internal',
|
||||
|
||||
Reference in new issue
Block a user