feat: complete account-bound profile switching and hardening (#78)
This commit is contained in:
31 files changed
+3612
-197
No files matched your search
@@ -1,11 +1,35 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export interface DeviceProfile {
|
||||
machineId: string;
|
||||
macMachineId: string;
|
||||
devDeviceId: string;
|
||||
sqmId: string;
|
||||
}
|
||||
|
||||
export interface DeviceProfileVersion {
|
||||
id: string;
|
||||
createdAt: number;
|
||||
label: string;
|
||||
profile: DeviceProfile;
|
||||
isCurrent: boolean;
|
||||
}
|
||||
|
||||
export interface DeviceProfilesSnapshot {
|
||||
currentStorage?: DeviceProfile;
|
||||
boundProfile?: DeviceProfile;
|
||||
history: DeviceProfileVersion[];
|
||||
baseline?: DeviceProfile;
|
||||
}
|
||||
|
||||
export interface Account {
|
||||
id: string; // UUID
|
||||
name: string;
|
||||
email: string;
|
||||
backup_file?: string;
|
||||
avatar_url?: string;
|
||||
deviceProfile?: DeviceProfile;
|
||||
deviceHistory?: DeviceProfileVersion[];
|
||||
created_at: string;
|
||||
last_used: string;
|
||||
}
|
||||
@@ -30,12 +54,36 @@ export interface AccountInfo {
|
||||
|
||||
// Zod Schemas for validation
|
||||
|
||||
export const DeviceProfileSchema = z.object({
|
||||
machineId: z.string(),
|
||||
macMachineId: z.string(),
|
||||
devDeviceId: z.string(),
|
||||
sqmId: z.string(),
|
||||
});
|
||||
|
||||
export const DeviceProfileVersionSchema = z.object({
|
||||
id: z.string(),
|
||||
createdAt: z.number(),
|
||||
label: z.string(),
|
||||
profile: DeviceProfileSchema,
|
||||
isCurrent: z.boolean(),
|
||||
});
|
||||
|
||||
export const DeviceProfilesSnapshotSchema = z.object({
|
||||
currentStorage: DeviceProfileSchema.optional(),
|
||||
boundProfile: DeviceProfileSchema.optional(),
|
||||
history: z.array(DeviceProfileVersionSchema),
|
||||
baseline: DeviceProfileSchema.optional(),
|
||||
});
|
||||
|
||||
export const AccountSchema = z.object({
|
||||
id: z.string(), // Relaxed from .uuid()
|
||||
name: z.string(), // Relaxed from .min(1)
|
||||
email: z.string(), // Relaxed from .email()
|
||||
backup_file: z.string().optional(),
|
||||
avatar_url: z.string().optional(),
|
||||
deviceProfile: DeviceProfileSchema.optional(),
|
||||
deviceHistory: z.array(DeviceProfileVersionSchema).optional(),
|
||||
created_at: z.string(),
|
||||
last_used: z.string(),
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { z } from 'zod';
|
||||
import { DeviceProfileSchema, DeviceProfileVersionSchema, type DeviceProfile, type DeviceProfileVersion } from './account';
|
||||
|
||||
export interface CloudTokenData {
|
||||
access_token: string;
|
||||
@@ -29,6 +30,8 @@ export interface CloudAccount {
|
||||
avatar_url?: string | null;
|
||||
token: CloudTokenData;
|
||||
quota?: CloudQuotaData;
|
||||
device_profile?: DeviceProfile;
|
||||
device_history?: DeviceProfileVersion[];
|
||||
created_at: number;
|
||||
last_used: number; // Unix timestamp
|
||||
status?: 'active' | 'rate_limited' | 'expired';
|
||||
@@ -65,6 +68,8 @@ export const CloudAccountSchema = z.object({
|
||||
avatar_url: z.string().optional().nullable(),
|
||||
token: CloudTokenDataSchema,
|
||||
quota: CloudQuotaDataSchema.optional(),
|
||||
device_profile: DeviceProfileSchema.optional(),
|
||||
device_history: z.array(DeviceProfileVersionSchema).optional(),
|
||||
created_at: z.number(),
|
||||
last_used: z.number(),
|
||||
status: z.enum(['active', 'rate_limited', 'expired']).optional(),
|
||||
|
||||
@@ -8,6 +8,8 @@ export const CloudAccountRowSchema = z.object({
|
||||
avatar_url: z.string().nullable(),
|
||||
token_json: z.string(),
|
||||
quota_json: z.string().nullable(),
|
||||
device_profile_json: z.string().nullable().optional(),
|
||||
device_history_json: z.string().nullable().optional(),
|
||||
created_at: z.number(),
|
||||
last_used: z.number(),
|
||||
status: z.string().nullable(),
|
||||
|
||||
Reference in new issue
Block a user