feat: complete account-bound profile switching and hardening (#78)
This commit is contained in:
31 files changed
+3612
-197
No files matched your search
@@ -2,9 +2,17 @@ import { z } from 'zod';
|
||||
import { os } from '@orpc/server';
|
||||
import {
|
||||
addGoogleAccount,
|
||||
bindCloudIdentityProfile,
|
||||
bindCloudIdentityProfileWithPayload,
|
||||
deleteCloudIdentityProfileRevision,
|
||||
listCloudAccounts,
|
||||
deleteCloudAccount,
|
||||
getCloudIdentityProfiles,
|
||||
openCloudIdentityStorageFolder,
|
||||
previewGenerateCloudIdentityProfile,
|
||||
refreshAccountQuota,
|
||||
restoreCloudIdentityProfileRevision,
|
||||
restoreCloudBaselineProfile,
|
||||
switchCloudAccount,
|
||||
getAutoSwitchEnabled,
|
||||
setAutoSwitchEnabled,
|
||||
@@ -12,8 +20,53 @@ import {
|
||||
startAuthFlow,
|
||||
} from './handler';
|
||||
import { CloudAccountSchema } from '../../types/cloudAccount';
|
||||
import {
|
||||
DeviceProfileSchema,
|
||||
DeviceProfilesSnapshotSchema,
|
||||
} from '../../types/account';
|
||||
import { CloudAccountRepo } from '../database/cloudHandler';
|
||||
import { logger } from '../../utils/logger';
|
||||
import { getSwitchMetricsSnapshot } from '../switchMetrics';
|
||||
import { getSwitchGuardSnapshot } from '../switchGuard';
|
||||
import { getDeviceHardeningSnapshot } from '../device/handler';
|
||||
|
||||
const switchOwnerSchema = z.enum(['local-account-switch', 'cloud-account-switch']);
|
||||
const switchMetricBucketSchema = z.object({
|
||||
switchSuccess: z.number(),
|
||||
switchFailure: z.number(),
|
||||
rollbackAttempt: z.number(),
|
||||
rollbackSuccess: z.number(),
|
||||
rollbackFailure: z.number(),
|
||||
failureReasons: z.record(z.string(), z.number()),
|
||||
lastFailure: z
|
||||
.object({
|
||||
reason: z.string(),
|
||||
message: z.string(),
|
||||
occurredAt: z.number(),
|
||||
})
|
||||
.nullable(),
|
||||
});
|
||||
const switchMetricsSnapshotSchema = z.object({
|
||||
local: switchMetricBucketSchema,
|
||||
cloud: switchMetricBucketSchema,
|
||||
});
|
||||
const switchGuardSnapshotSchema = z.object({
|
||||
activeOwner: switchOwnerSchema.nullable(),
|
||||
pendingOwners: z.array(switchOwnerSchema),
|
||||
pendingCount: z.number(),
|
||||
});
|
||||
const switchStatusSnapshotSchema = z.object({
|
||||
metrics: switchMetricsSnapshotSchema,
|
||||
guard: switchGuardSnapshotSchema,
|
||||
hardening: z.object({
|
||||
consecutiveApplyFailures: z.number(),
|
||||
safeModeActive: z.boolean(),
|
||||
safeModeUntil: z.number().nullable(),
|
||||
lastFailureReason: z.string().nullable(),
|
||||
lastFailureStage: z.string().nullable(),
|
||||
lastFailureAt: z.number().nullable(),
|
||||
}),
|
||||
});
|
||||
|
||||
export const cloudRouter = os.router({
|
||||
addGoogleAccount: os
|
||||
@@ -77,4 +130,62 @@ export const cloudRouter = os.router({
|
||||
throw error;
|
||||
}
|
||||
}),
|
||||
|
||||
getSwitchStatus: os.output(switchStatusSnapshotSchema).handler(async () => {
|
||||
return {
|
||||
metrics: getSwitchMetricsSnapshot(),
|
||||
guard: getSwitchGuardSnapshot(),
|
||||
hardening: getDeviceHardeningSnapshot(),
|
||||
};
|
||||
}),
|
||||
|
||||
getIdentityProfiles: os
|
||||
.input(z.object({ accountId: z.string() }))
|
||||
.output(DeviceProfilesSnapshotSchema)
|
||||
.handler(async ({ input }) => {
|
||||
return getCloudIdentityProfiles(input.accountId);
|
||||
}),
|
||||
|
||||
previewIdentityProfile: os.output(DeviceProfileSchema).handler(async () => {
|
||||
return previewGenerateCloudIdentityProfile();
|
||||
}),
|
||||
|
||||
bindIdentityProfile: os
|
||||
.input(z.object({ accountId: z.string(), mode: z.enum(['capture', 'generate']) }))
|
||||
.output(DeviceProfileSchema)
|
||||
.handler(async ({ input }) => {
|
||||
return bindCloudIdentityProfile(input.accountId, input.mode);
|
||||
}),
|
||||
|
||||
bindIdentityProfileWithPayload: os
|
||||
.input(z.object({ accountId: z.string(), profile: DeviceProfileSchema }))
|
||||
.output(DeviceProfileSchema)
|
||||
.handler(async ({ input }) => {
|
||||
return bindCloudIdentityProfileWithPayload(input.accountId, input.profile);
|
||||
}),
|
||||
|
||||
restoreIdentityProfileRevision: os
|
||||
.input(z.object({ accountId: z.string(), versionId: z.string() }))
|
||||
.output(DeviceProfileSchema)
|
||||
.handler(async ({ input }) => {
|
||||
return restoreCloudIdentityProfileRevision(input.accountId, input.versionId);
|
||||
}),
|
||||
|
||||
restoreBaselineProfile: os
|
||||
.input(z.object({ accountId: z.string() }))
|
||||
.output(DeviceProfileSchema)
|
||||
.handler(async ({ input }) => {
|
||||
return restoreCloudBaselineProfile(input.accountId);
|
||||
}),
|
||||
|
||||
deleteIdentityProfileRevision: os
|
||||
.input(z.object({ accountId: z.string(), versionId: z.string() }))
|
||||
.output(z.void())
|
||||
.handler(async ({ input }) => {
|
||||
await deleteCloudIdentityProfileRevision(input.accountId, input.versionId);
|
||||
}),
|
||||
|
||||
openIdentityStorageFolder: os.output(z.void()).handler(async () => {
|
||||
await openCloudIdentityStorageFolder();
|
||||
}),
|
||||
});
|
||||
Reference in new issue
Block a user