feat(P3.T2): DeviceRecord.revokedAt + revokeDevice wrapper
Extend DeviceRecord with revokedAt field, update registerDevice and listOwnDevices selects to include revoked_at, add revokeDevice RPC helper, update db-types to reflect T1 migration schema, and add vitest coverage for all new behaviour. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,7 @@ export interface DeviceRecord {
|
||||
name: string;
|
||||
platform: DevicePlatform;
|
||||
lastSeenAt: string;
|
||||
revokedAt: string | null;
|
||||
}
|
||||
|
||||
export async function registerDevice(
|
||||
@@ -32,7 +33,7 @@ export async function registerDevice(
|
||||
name: params.name,
|
||||
platform: params.platform,
|
||||
})
|
||||
.select('id, name, platform, last_seen_at')
|
||||
.select('id, name, platform, last_seen_at, revoked_at')
|
||||
.single();
|
||||
if (error) throw error;
|
||||
|
||||
@@ -41,6 +42,7 @@ export async function registerDevice(
|
||||
name: data.name,
|
||||
platform: data.platform,
|
||||
lastSeenAt: data.last_seen_at,
|
||||
revokedAt: data.revoked_at,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -50,7 +52,7 @@ export async function listOwnDevices(client: AppSupabaseClient): Promise<DeviceR
|
||||
|
||||
const { data, error } = await client
|
||||
.from('devices')
|
||||
.select('id, name, platform, last_seen_at')
|
||||
.select('id, name, platform, last_seen_at, revoked_at')
|
||||
.eq('user_id', session.user.id)
|
||||
.order('last_seen_at', { ascending: false });
|
||||
if (error) throw error;
|
||||
@@ -60,6 +62,7 @@ export async function listOwnDevices(client: AppSupabaseClient): Promise<DeviceR
|
||||
name: row.name,
|
||||
platform: row.platform,
|
||||
lastSeenAt: row.last_seen_at,
|
||||
revokedAt: row.revoked_at,
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -74,6 +77,14 @@ export async function touchDeviceLastSeen(
|
||||
if (error) throw error;
|
||||
}
|
||||
|
||||
export async function revokeDevice(
|
||||
client: AppSupabaseClient,
|
||||
deviceId: string,
|
||||
): Promise<void> {
|
||||
const { error } = await client.rpc('revoke_device', { p_device_id: deviceId });
|
||||
if (error) throw new Error(error.message);
|
||||
}
|
||||
|
||||
// Intentional re-exports so app layers only need @chat-app/shared/auth.
|
||||
export type { SecretStore } from './secure-storage';
|
||||
export { toBase64 as base64FromBytes, fromBase64 as bytesFromBase64 };
|
||||
|
||||
Reference in New Issue
Block a user