mirror of
https://github.com/nexu-io/open-design.git
synced 2026-10-27 09:51:12 +01:00
fix(auth): keep pending login credentials inactive until completion
Refs: OPEND-4373
This commit is contained in:
@@ -397,6 +397,7 @@ export interface VelaApiContext {
|
||||
}
|
||||
|
||||
interface VelaProfileShape {
|
||||
pendingLogin?: unknown;
|
||||
controlKeyId?: string;
|
||||
controlKey?: string;
|
||||
runtimeKey?: string;
|
||||
@@ -530,7 +531,7 @@ function readRawVelaLoginStatus(
|
||||
const file = readConfigFile();
|
||||
const stored = file?.profiles?.[profile];
|
||||
const storedRuntimeKey = stored?.runtimeKey?.trim() ?? '';
|
||||
if (!storedRuntimeKey) {
|
||||
if (!storedRuntimeKey || stored?.pendingLogin) {
|
||||
return {
|
||||
loggedIn: false,
|
||||
loginInFlight,
|
||||
@@ -747,8 +748,9 @@ function velaControlKeyDigest(controlKey: string): string {
|
||||
export function readVelaControlApiContext(
|
||||
env: NodeJS.ProcessEnv = process.env,
|
||||
configuredEnv: Record<string, string> = {},
|
||||
allowPendingLogin = false,
|
||||
): VelaControlApiContext | null {
|
||||
const context = readRawVelaControlApiContext(env, configuredEnv);
|
||||
const context = readRawVelaControlApiContext(env, configuredEnv, allowPendingLogin);
|
||||
if (
|
||||
context
|
||||
&& expiredVelaControlKeys.has(velaControlKeyDigest(context.controlKey))
|
||||
@@ -759,6 +761,7 @@ export function readVelaControlApiContext(
|
||||
function readRawVelaControlApiContext(
|
||||
env: NodeJS.ProcessEnv = process.env,
|
||||
configuredEnv: Record<string, string> = {},
|
||||
allowPendingLogin = false,
|
||||
): VelaControlApiContext | null {
|
||||
const mergedEnv = mergeVelaEnv(env, configuredEnv);
|
||||
const profile = resolveAmrProfile(mergedEnv);
|
||||
@@ -778,7 +781,7 @@ function readRawVelaControlApiContext(
|
||||
const apiContext = readVelaApiContext(env, configuredEnv, snapshot);
|
||||
const stored = snapshot.stored;
|
||||
const controlKey = stored?.controlKey?.trim() ?? '';
|
||||
if (!controlKey) return null;
|
||||
if (!controlKey || (stored?.pendingLogin && !allowPendingLogin)) return null;
|
||||
return {
|
||||
...apiContext,
|
||||
controlKey,
|
||||
@@ -825,6 +828,7 @@ export function forgetVelaLogin(env: NodeJS.ProcessEnv = process.env): void {
|
||||
delete keptProfileConfig.controlKeyId;
|
||||
delete keptProfileConfig.runtimeKey;
|
||||
delete keptProfileConfig.user;
|
||||
delete keptProfileConfig.pendingLogin;
|
||||
const nextProfiles = { ...parsed.profiles };
|
||||
nextProfiles[profile] = keptProfileConfig;
|
||||
writeFileSync(
|
||||
|
||||
@@ -1514,7 +1514,7 @@ export function registerVelaRoutes(app: Express, deps: RegisterVelaRoutesDeps):
|
||||
acceptCredentials: () => {
|
||||
const mergedEnv = mergeVelaEnv(env, configuredEnv);
|
||||
const target = readVelaLogoutTarget(mergedEnv);
|
||||
if (!target?.controlKeyId || !readVelaControlApiContext(env, configuredEnv) || mergedEnv.VELA_RUNTIME_KEY?.trim() || mergedEnv.VELA_CONTROL_KEY?.trim()) throw new Error('saved_credentials_not_active');
|
||||
if (!target?.controlKeyId || !readVelaControlApiContext(env, configuredEnv, true) || mergedEnv.VELA_RUNTIME_KEY?.trim() || mergedEnv.VELA_CONTROL_KEY?.trim()) throw new Error('saved_credentials_not_active');
|
||||
clearVelaAuthorizationState();
|
||||
clearAllVelaLiveAccounts();
|
||||
clearVelaWalletSnapshotCache();
|
||||
|
||||
@@ -108,6 +108,14 @@ describe('resolveAmrProfile', () => {
|
||||
});
|
||||
|
||||
describe('readVelaLoginStatus', () => {
|
||||
it('does not publish credentials with an unfinished receipt after a daemon restart', () => {
|
||||
writeConfig({ profiles: { local: { controlKey: 'pending-control', runtimeKey: 'pending-runtime', pendingLogin: { deviceId: 'attempt' }, user: {id: 'u', email: 'u@example.test'} } } });
|
||||
const env = { OPEN_DESIGN_AMR_PROFILE: 'local' };
|
||||
expect(readVelaLoginStatus(env)).toMatchObject({loggedIn: false, sessionState: 'signed_out'});
|
||||
expect(readVelaControlApiContext(env)).toBeNull();
|
||||
expect(readVelaControlApiContext(env, {}, true)?.controlKey).toBe('pending-control');
|
||||
});
|
||||
|
||||
afterEach(() => clearVelaAuthorizationState());
|
||||
|
||||
it('marks only the rejected credential revision as requiring sign-in again', () => {
|
||||
|
||||
Reference in New Issue
Block a user