Merge pull request #1926 from useautumn/fix/cli-scopes-3
fix: 🐛 cli auth for the last time
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
import { LEAF_OAUTH_SCOPES } from "@autumn/shared/leafOAuthScopes";
|
||||
import { OPENID_SCOPES } from "@autumn/shared/scopeDefinitions";
|
||||
import {
|
||||
LEGACY_SCOPE_ALIASES,
|
||||
OPENID_SCOPES,
|
||||
} from "@autumn/shared/scopeDefinitions";
|
||||
|
||||
const leafScopeSet = new Set<string>(LEAF_OAUTH_SCOPES);
|
||||
const oauthPassthroughScopeSet = new Set<string>(["offline_access"]);
|
||||
@@ -11,8 +14,12 @@ export const getDefaultOAuthScopes = (requestedScopes?: string[] | null) => {
|
||||
? requestedScopes
|
||||
: [...LEAF_OAUTH_SCOPES, ...oauthPassthroughScopeSet];
|
||||
|
||||
// Issued scopes must echo the client's request verbatim (better-auth
|
||||
// rejects rewrites), so legacy CRUDL aliases are used for filtering only.
|
||||
return [...new Set(requested)].filter(
|
||||
(scope) => leafScopeSet.has(scope) || oauthPassthroughScopeSet.has(scope),
|
||||
(scope) =>
|
||||
leafScopeSet.has(LEGACY_SCOPE_ALIASES[scope] ?? scope) ||
|
||||
oauthPassthroughScopeSet.has(scope),
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import { AppEnv, ErrCode, RecaseError, Scopes } from "@autumn/shared";
|
||||
import {
|
||||
AppEnv,
|
||||
ErrCode,
|
||||
LEGACY_SCOPE_ALIASES,
|
||||
RecaseError,
|
||||
Scopes,
|
||||
} from "@autumn/shared";
|
||||
import { createRoute } from "@/honoMiddlewares/routeHandler.js";
|
||||
import { isMcpOAuthClientId } from "@/internal/auth/oauth/mcpOAuthScopes.js";
|
||||
import {
|
||||
@@ -84,7 +90,15 @@ export const handleCreateOAuthApiKeys = createRoute({
|
||||
statusCode: 401,
|
||||
});
|
||||
}
|
||||
const apiKeyScopes = requestedScopes ?? tokenRecord.scopes;
|
||||
// Tokens may carry legacy CRUDL scopes (old CLI); store modern R/W on keys.
|
||||
const apiKeyScopes = [
|
||||
...new Set(
|
||||
(requestedScopes ?? tokenRecord.scopes).map(
|
||||
(scope) => LEGACY_SCOPE_ALIASES[scope] ?? scope,
|
||||
),
|
||||
),
|
||||
];
|
||||
|
||||
if (await isMcpOAuthClientId({ clientId, ctx })) {
|
||||
throw new RecaseError({
|
||||
message: "MCP OAuth clients must use OAuth access tokens directly",
|
||||
|
||||
@@ -64,6 +64,33 @@ describe("getRequestedScopesForMcpClient", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
test("keeps legacy CRUDL scopes (old CLI) whose alias is leaf-allowed, verbatim", () => {
|
||||
expect(
|
||||
getDefaultOAuthScopes([
|
||||
"customers:create",
|
||||
"customers:read",
|
||||
"customers:list",
|
||||
"customers:update",
|
||||
"customers:delete",
|
||||
"features:create",
|
||||
"features:read",
|
||||
"plans:update",
|
||||
"apiKeys:create",
|
||||
"organisation:read",
|
||||
]),
|
||||
).toEqual([
|
||||
"customers:create",
|
||||
"customers:read",
|
||||
"customers:list",
|
||||
"customers:update",
|
||||
"customers:delete",
|
||||
"features:create",
|
||||
"features:read",
|
||||
"plans:update",
|
||||
"organisation:read",
|
||||
]);
|
||||
});
|
||||
|
||||
test("strips OAuth protocol scopes from resource scopes", () => {
|
||||
expect(
|
||||
getOAuthResourceScopes([
|
||||
|
||||
Reference in New Issue
Block a user