refactor(infra): reuse device auth scope normalization

This commit is contained in:
Peter Steinberger
2026-02-17 00:10:41 +00:00
parent fbd3786e7a
commit b9aed3a07c

View File

@@ -1,4 +1,5 @@
import { randomUUID } from "node:crypto";
import { normalizeDeviceAuthScopes } from "../shared/device-auth.js";
import {
createAsyncLock,
pruneExpiredPending,
@@ -150,20 +151,6 @@ function mergeScopes(...items: Array<string[] | undefined>): string[] | undefine
return [...scopes];
}
function normalizeScopes(scopes: string[] | undefined): string[] {
if (!Array.isArray(scopes)) {
return [];
}
const out = new Set<string>();
for (const scope of scopes) {
const trimmed = scope.trim();
if (trimmed) {
out.add(trimmed);
}
}
return [...out].toSorted();
}
function scopesAllow(requested: string[], allowed: string[]): boolean {
if (requested.length === 0) {
return true;
@@ -283,7 +270,7 @@ export async function approveDevicePairing(
const tokens = existing?.tokens ? { ...existing.tokens } : {};
const roleForToken = normalizeRole(pending.role);
if (roleForToken) {
const nextScopes = normalizeScopes(pending.scopes);
const nextScopes = normalizeDeviceAuthScopes(pending.scopes);
const existingToken = tokens[roleForToken];
const now = Date.now();
tokens[roleForToken] = {
@@ -407,7 +394,7 @@ export async function verifyDeviceToken(params: {
if (!verifyPairingToken(params.token, entry.token)) {
return { ok: false, reason: "token-mismatch" };
}
const requestedScopes = normalizeScopes(params.scopes);
const requestedScopes = normalizeDeviceAuthScopes(params.scopes);
if (!scopesAllow(requestedScopes, entry.scopes)) {
return { ok: false, reason: "scope-mismatch" };
}
@@ -428,7 +415,7 @@ export async function ensureDeviceToken(params: {
}): Promise<DeviceAuthToken | null> {
return await withLock(async () => {
const state = await loadState(params.baseDir);
const requestedScopes = normalizeScopes(params.scopes);
const requestedScopes = normalizeDeviceAuthScopes(params.scopes);
const context = resolveDeviceTokenUpdateContext({
state,
deviceId: params.deviceId,
@@ -499,7 +486,9 @@ export async function rotateDeviceToken(params: {
return null;
}
const { device, role, tokens, existing } = context;
const requestedScopes = normalizeScopes(params.scopes ?? existing?.scopes ?? device.scopes);
const requestedScopes = normalizeDeviceAuthScopes(
params.scopes ?? existing?.scopes ?? device.scopes,
);
const now = Date.now();
const next = buildDeviceAuthToken({
role,