@rolino/local-auth 0.6.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/README.md +8 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# `@rolino/local-auth`
|
|
2
2
|
|
|
3
|
-
Node-only OAuth token storage shared by Rolino's CLI and local stdio MCP
|
|
4
|
-
adapter. Token sets are scoped by host, issuer, client, and exact resource.
|
|
5
|
-
The store refreshes short-lived access tokens under one rotation lock and
|
|
6
|
-
writes the owner-only file atomically. Environment API keys still take
|
|
7
|
-
precedence for headless automation. The removed interactive credential is
|
|
8
|
-
never read or converted.
|
|
3
|
+
Node-only OAuth token storage shared by Rolino's CLI and local stdio MCP
|
|
4
|
+
adapter. Token sets are scoped by host, issuer, client, and exact resource.
|
|
5
|
+
The store refreshes short-lived access tokens under one rotation lock and
|
|
6
|
+
writes the owner-only file atomically. Environment API keys still take
|
|
7
|
+
precedence for headless automation. The removed interactive credential is
|
|
8
|
+
never read or converted.
|
|
9
9
|
|
|
10
10
|
This package must not be used by the browser, public SDK, application routes,
|
|
11
11
|
or server domain services. It is published only as a supported transitive
|
|
@@ -14,8 +14,8 @@ file format as a public credential-storage API.
|
|
|
14
14
|
|
|
15
15
|
## Support, security, and license
|
|
16
16
|
|
|
17
|
-
Stable releases are published only after the maintainer approves the release
|
|
18
|
-
gate. Report bugs through the
|
|
17
|
+
Stable releases are published only after the maintainer approves the release
|
|
18
|
+
gate. Report bugs through the
|
|
19
19
|
[Rolino issue tracker](https://github.com/deifos/rolino/issues) and security
|
|
20
20
|
issues through the repository's
|
|
21
21
|
[security policy](https://github.com/deifos/rolino/security/policy).
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n chmodSync,\n existsSync,\n mkdirSync,\n readFileSync,\n renameSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport { normalizeRolinoBaseUrl } from \"@rolino/sdk\";\n\nexport const ROLINO_CLI_OAUTH_CLIENT_ID = \"rolino-cli\";\n\nexport type OAuthTokenSet = {\n host: string;\n issuer: string;\n clientId: string;\n resource: string;\n accessToken: string;\n accessTokenExpiresAt: string;\n refreshToken: string;\n refreshTokenExpiresAt: string;\n scopes: string[];\n};\n\ntype OAuthTokenStore = {\n version: 2;\n tokens: Record<string, OAuthTokenSet>;\n};\n\ntype RefreshableTokenProvider = (() => Promise<string | undefined>) & {\n refresh: () => Promise<string | undefined>;\n};\n\nconst refreshLocks = new Map<string, Promise<OAuthTokenSet>>();\n\nfunction defaultConfigDirectory(env: Record<string, string | undefined>) {\n if (env.ROLINO_CONFIG_DIR) return env.ROLINO_CONFIG_DIR;\n if (process.platform === \"win32\" && env.APPDATA) return join(env.APPDATA, \"Rolino\");\n if (process.platform === \"darwin\") return join(homedir(), \"Library\", \"Application Support\", \"Rolino\");\n return join(env.XDG_CONFIG_HOME ?? join(homedir(), \".config\"), \"rolino\");\n}\n\nexport function oauthTokenStorePath(\n env: Record<string, string | undefined> = process.env,\n) {\n return join(defaultConfigDirectory(env), \"oauth-tokens.json\");\n}\n\nexport function oauthConfiguration(baseUrl: string) {\n const host = normalizeRolinoBaseUrl(baseUrl);\n return {\n host,\n issuer: `${host}/api/auth`,\n clientId: ROLINO_CLI_OAUTH_CLIENT_ID,\n resource: `${host}/api/v1`,\n };\n}\n\nfunction tokenKey(input: Pick<OAuthTokenSet, \"host\" | \"issuer\" | \"clientId\" | \"resource\">) {\n return JSON.stringify([input.host, input.issuer, input.clientId, input.resource]);\n}\n\nfunction isTokenSet(value: unknown): value is OAuthTokenSet {\n if (!value || typeof value !== \"object\") return false;\n const token = value as Partial<OAuthTokenSet>;\n return [token.host, token.issuer, token.clientId, token.resource, token.accessToken,\n token.accessTokenExpiresAt, token.refreshToken, token.refreshTokenExpiresAt]\n .every((item) => typeof item === \"string\" && item.length > 0)\n && Array.isArray(token.scopes)\n && token.scopes.every((scope) => typeof scope === \"string\");\n}\n\nfunction readStore(env: Record<string, string | undefined>): OAuthTokenStore {\n const path = oauthTokenStorePath(env);\n if (!existsSync(path)) return { version: 2, tokens: {} };\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as Partial<OAuthTokenStore>;\n if (\n parsed.version !== 2\n || !parsed.tokens\n || typeof parsed.tokens !== \"object\"\n || !Object.values(parsed.tokens).every(isTokenSet)\n ) throw new Error(\"invalid\");\n return parsed as OAuthTokenStore;\n } catch {\n throw new TypeError(`Rolino could not read its OAuth token store at ${path}.`);\n }\n}\n\nfunction writeStore(store: OAuthTokenStore, env: Record<string, string | undefined>) {\n const path = oauthTokenStorePath(env);\n const temporary = `${path}.${process.pid}.tmp`;\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\n writeFileSync(temporary, `${JSON.stringify(store, null, 2)}\\n`, {\n encoding: \"utf8\",\n mode: 0o600,\n });\n chmodSync(temporary, 0o600);\n renameSync(temporary, path);\n chmodSync(path, 0o600);\n return path;\n}\n\nexport function loadOAuthTokenSet(\n baseUrl: string,\n env: Record<string, string | undefined> = process.env,\n) {\n const configuration = oauthConfiguration(baseUrl);\n return readStore(env).tokens[tokenKey(configuration)] ?? null;\n}\n\nexport function saveOAuthTokenSet(\n tokenSet: OAuthTokenSet,\n env: Record<string, string | undefined> = process.env,\n) {\n const configuration = oauthConfiguration(tokenSet.host);\n if (\n tokenSet.host !== configuration.host\n || tokenSet.issuer !== configuration.issuer\n || tokenSet.clientId !== configuration.clientId\n || tokenSet.resource !== configuration.resource\n ) throw new TypeError(\"The OAuth token set does not match the Rolino host.\");\n const store = readStore(env);\n store.tokens[tokenKey(tokenSet)] = tokenSet;\n const path = writeStore(store, env);\n const retiredInteractiveCredential = join(defaultConfigDirectory(env), \"credentials.json\");\n if (existsSync(retiredInteractiveCredential)) unlinkSync(retiredInteractiveCredential);\n return path;\n}\n\nexport function clearOAuthTokenSet(\n baseUrl: string,\n env: Record<string, string | undefined> = process.env,\n) {\n const path = oauthTokenStorePath(env);\n const store = readStore(env);\n const key = tokenKey(oauthConfiguration(baseUrl));\n const existed = Boolean(store.tokens[key]);\n delete store.tokens[key];\n if (!Object.keys(store.tokens).length) {\n if (existsSync(path)) unlinkSync(path);\n } else {\n writeStore(store, env);\n }\n return existed;\n}\n\nasync function refreshOAuthTokenSet(options: {\n baseUrl: string;\n env: Record<string, string | undefined>;\n fetch: typeof globalThis.fetch;\n}) {\n const current = loadOAuthTokenSet(options.baseUrl, options.env);\n if (!current) throw new TypeError(\"OAuth sign-in is required. Run `rolino auth login`.\");\n const key = tokenKey(current);\n const existing = refreshLocks.get(key);\n if (existing) return existing;\n\n const refresh = (async () => {\n const body = new URLSearchParams({\n grant_type: \"refresh_token\",\n refresh_token: current.refreshToken,\n client_id: current.clientId,\n resource: current.resource,\n });\n const response = await options.fetch(`${current.issuer}/oauth2/token`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/x-www-form-urlencoded\", accept: \"application/json\" },\n body,\n });\n const payload = await response.json().catch(() => null) as Record<string, unknown> | null;\n if (!response.ok || !payload || typeof payload.access_token !== \"string\") {\n throw new TypeError(\"OAuth sign-in is required. Run `rolino auth login`.\");\n }\n const expiresIn = typeof payload.expires_in === \"number\" ? payload.expires_in : 300;\n const refreshed: OAuthTokenSet = {\n ...current,\n accessToken: payload.access_token,\n accessTokenExpiresAt: new Date(Date.now() + expiresIn * 1_000).toISOString(),\n refreshToken: typeof payload.refresh_token === \"string\" ? payload.refresh_token : current.refreshToken,\n scopes: typeof payload.scope === \"string\" ? payload.scope.split(/\\s+/).filter(Boolean) : current.scopes,\n };\n saveOAuthTokenSet(refreshed, options.env);\n return refreshed;\n })().finally(() => refreshLocks.delete(key));\n refreshLocks.set(key, refresh);\n return refresh;\n}\n\nexport function createOAuthAccessTokenProvider(options: {\n baseUrl: string;\n env?: Record<string, string | undefined>;\n fetch?: typeof globalThis.fetch;\n}): RefreshableTokenProvider {\n const env = options.env ?? process.env;\n const fetchImplementation = options.fetch ?? globalThis.fetch;\n const obtain = async (force: boolean) => {\n if (env.ROLINO_TOKEN) return env.ROLINO_TOKEN;\n const token = loadOAuthTokenSet(options.baseUrl, env);\n if (!token) return undefined;\n if (!force && Date.parse(token.accessTokenExpiresAt) - Date.now() > 30_000) {\n return token.accessToken;\n }\n return (await refreshOAuthTokenSet({\n baseUrl: options.baseUrl,\n env,\n fetch: fetchImplementation,\n })).accessToken;\n };\n const provider = (() => obtain(false)) as RefreshableTokenProvider;\n provider.refresh = () => obtain(true);\n return provider;\n}\n\nexport function resolveLocalAuthentication(\n baseUrl: string,\n env: Record<string, string | undefined> = process.env,\n) {\n if (env.ROLINO_TOKEN) return { source: \"environment\" as const, tokenSet: null };\n const tokenSet = loadOAuthTokenSet(baseUrl, env);\n return tokenSet\n ? { source: \"oauth\" as const, tokenSet }\n : { source: \"none\" as const, tokenSet: null };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\r\n chmodSync,\r\n existsSync,\r\n mkdirSync,\r\n readFileSync,\r\n renameSync,\r\n unlinkSync,\r\n writeFileSync,\r\n} from \"node:fs\";\r\nimport { homedir } from \"node:os\";\r\nimport { dirname, join } from \"node:path\";\r\n\r\nimport { normalizeRolinoBaseUrl } from \"@rolino/sdk\";\r\n\r\nexport const ROLINO_CLI_OAUTH_CLIENT_ID = \"rolino-cli\";\r\n\r\nexport type OAuthTokenSet = {\r\n host: string;\r\n issuer: string;\r\n clientId: string;\r\n resource: string;\r\n accessToken: string;\r\n accessTokenExpiresAt: string;\r\n refreshToken: string;\r\n refreshTokenExpiresAt: string;\r\n scopes: string[];\r\n};\r\n\r\ntype OAuthTokenStore = {\r\n version: 2;\r\n tokens: Record<string, OAuthTokenSet>;\r\n};\r\n\r\ntype RefreshableTokenProvider = (() => Promise<string | undefined>) & {\r\n refresh: () => Promise<string | undefined>;\r\n};\r\n\r\nconst refreshLocks = new Map<string, Promise<OAuthTokenSet>>();\r\n\r\nfunction defaultConfigDirectory(env: Record<string, string | undefined>) {\r\n if (env.ROLINO_CONFIG_DIR) return env.ROLINO_CONFIG_DIR;\r\n if (process.platform === \"win32\" && env.APPDATA) return join(env.APPDATA, \"Rolino\");\r\n if (process.platform === \"darwin\") return join(homedir(), \"Library\", \"Application Support\", \"Rolino\");\r\n return join(env.XDG_CONFIG_HOME ?? join(homedir(), \".config\"), \"rolino\");\r\n}\r\n\r\nexport function oauthTokenStorePath(\r\n env: Record<string, string | undefined> = process.env,\r\n) {\r\n return join(defaultConfigDirectory(env), \"oauth-tokens.json\");\r\n}\r\n\r\nexport function oauthConfiguration(baseUrl: string) {\r\n const host = normalizeRolinoBaseUrl(baseUrl);\r\n return {\r\n host,\r\n issuer: `${host}/api/auth`,\r\n clientId: ROLINO_CLI_OAUTH_CLIENT_ID,\r\n resource: `${host}/api/v1`,\r\n };\r\n}\r\n\r\nfunction tokenKey(input: Pick<OAuthTokenSet, \"host\" | \"issuer\" | \"clientId\" | \"resource\">) {\r\n return JSON.stringify([input.host, input.issuer, input.clientId, input.resource]);\r\n}\r\n\r\nfunction isTokenSet(value: unknown): value is OAuthTokenSet {\r\n if (!value || typeof value !== \"object\") return false;\r\n const token = value as Partial<OAuthTokenSet>;\r\n return [token.host, token.issuer, token.clientId, token.resource, token.accessToken,\r\n token.accessTokenExpiresAt, token.refreshToken, token.refreshTokenExpiresAt]\r\n .every((item) => typeof item === \"string\" && item.length > 0)\r\n && Array.isArray(token.scopes)\r\n && token.scopes.every((scope) => typeof scope === \"string\");\r\n}\r\n\r\nfunction readStore(env: Record<string, string | undefined>): OAuthTokenStore {\r\n const path = oauthTokenStorePath(env);\r\n if (!existsSync(path)) return { version: 2, tokens: {} };\r\n try {\r\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as Partial<OAuthTokenStore>;\r\n if (\r\n parsed.version !== 2\r\n || !parsed.tokens\r\n || typeof parsed.tokens !== \"object\"\r\n || !Object.values(parsed.tokens).every(isTokenSet)\r\n ) throw new Error(\"invalid\");\r\n return parsed as OAuthTokenStore;\r\n } catch {\r\n throw new TypeError(`Rolino could not read its OAuth token store at ${path}.`);\r\n }\r\n}\r\n\r\nfunction writeStore(store: OAuthTokenStore, env: Record<string, string | undefined>) {\r\n const path = oauthTokenStorePath(env);\r\n const temporary = `${path}.${process.pid}.tmp`;\r\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\r\n writeFileSync(temporary, `${JSON.stringify(store, null, 2)}\\n`, {\r\n encoding: \"utf8\",\r\n mode: 0o600,\r\n });\r\n chmodSync(temporary, 0o600);\r\n renameSync(temporary, path);\r\n chmodSync(path, 0o600);\r\n return path;\r\n}\r\n\r\nexport function loadOAuthTokenSet(\r\n baseUrl: string,\r\n env: Record<string, string | undefined> = process.env,\r\n) {\r\n const configuration = oauthConfiguration(baseUrl);\r\n return readStore(env).tokens[tokenKey(configuration)] ?? null;\r\n}\r\n\r\nexport function saveOAuthTokenSet(\r\n tokenSet: OAuthTokenSet,\r\n env: Record<string, string | undefined> = process.env,\r\n) {\r\n const configuration = oauthConfiguration(tokenSet.host);\r\n if (\r\n tokenSet.host !== configuration.host\r\n || tokenSet.issuer !== configuration.issuer\r\n || tokenSet.clientId !== configuration.clientId\r\n || tokenSet.resource !== configuration.resource\r\n ) throw new TypeError(\"The OAuth token set does not match the Rolino host.\");\r\n const store = readStore(env);\r\n store.tokens[tokenKey(tokenSet)] = tokenSet;\r\n const path = writeStore(store, env);\r\n const retiredInteractiveCredential = join(defaultConfigDirectory(env), \"credentials.json\");\r\n if (existsSync(retiredInteractiveCredential)) unlinkSync(retiredInteractiveCredential);\r\n return path;\r\n}\r\n\r\nexport function clearOAuthTokenSet(\r\n baseUrl: string,\r\n env: Record<string, string | undefined> = process.env,\r\n) {\r\n const path = oauthTokenStorePath(env);\r\n const store = readStore(env);\r\n const key = tokenKey(oauthConfiguration(baseUrl));\r\n const existed = Boolean(store.tokens[key]);\r\n delete store.tokens[key];\r\n if (!Object.keys(store.tokens).length) {\r\n if (existsSync(path)) unlinkSync(path);\r\n } else {\r\n writeStore(store, env);\r\n }\r\n return existed;\r\n}\r\n\r\nasync function refreshOAuthTokenSet(options: {\r\n baseUrl: string;\r\n env: Record<string, string | undefined>;\r\n fetch: typeof globalThis.fetch;\r\n}) {\r\n const current = loadOAuthTokenSet(options.baseUrl, options.env);\r\n if (!current) throw new TypeError(\"OAuth sign-in is required. Run `rolino auth login`.\");\r\n const key = tokenKey(current);\r\n const existing = refreshLocks.get(key);\r\n if (existing) return existing;\r\n\r\n const refresh = (async () => {\r\n const body = new URLSearchParams({\r\n grant_type: \"refresh_token\",\r\n refresh_token: current.refreshToken,\r\n client_id: current.clientId,\r\n resource: current.resource,\r\n });\r\n const response = await options.fetch(`${current.issuer}/oauth2/token`, {\r\n method: \"POST\",\r\n headers: { \"content-type\": \"application/x-www-form-urlencoded\", accept: \"application/json\" },\r\n body,\r\n });\r\n const payload = await response.json().catch(() => null) as Record<string, unknown> | null;\r\n if (!response.ok || !payload || typeof payload.access_token !== \"string\") {\r\n throw new TypeError(\"OAuth sign-in is required. Run `rolino auth login`.\");\r\n }\r\n const expiresIn = typeof payload.expires_in === \"number\" ? payload.expires_in : 300;\r\n const refreshed: OAuthTokenSet = {\r\n ...current,\r\n accessToken: payload.access_token,\r\n accessTokenExpiresAt: new Date(Date.now() + expiresIn * 1_000).toISOString(),\r\n refreshToken: typeof payload.refresh_token === \"string\" ? payload.refresh_token : current.refreshToken,\r\n scopes: typeof payload.scope === \"string\" ? payload.scope.split(/\\s+/).filter(Boolean) : current.scopes,\r\n };\r\n saveOAuthTokenSet(refreshed, options.env);\r\n return refreshed;\r\n })().finally(() => refreshLocks.delete(key));\r\n refreshLocks.set(key, refresh);\r\n return refresh;\r\n}\r\n\r\nexport function createOAuthAccessTokenProvider(options: {\r\n baseUrl: string;\r\n env?: Record<string, string | undefined>;\r\n fetch?: typeof globalThis.fetch;\r\n}): RefreshableTokenProvider {\r\n const env = options.env ?? process.env;\r\n const fetchImplementation = options.fetch ?? globalThis.fetch;\r\n const obtain = async (force: boolean) => {\r\n if (env.ROLINO_TOKEN) return env.ROLINO_TOKEN;\r\n const token = loadOAuthTokenSet(options.baseUrl, env);\r\n if (!token) return undefined;\r\n if (!force && Date.parse(token.accessTokenExpiresAt) - Date.now() > 30_000) {\r\n return token.accessToken;\r\n }\r\n return (await refreshOAuthTokenSet({\r\n baseUrl: options.baseUrl,\r\n env,\r\n fetch: fetchImplementation,\r\n })).accessToken;\r\n };\r\n const provider = (() => obtain(false)) as RefreshableTokenProvider;\r\n provider.refresh = () => obtain(true);\r\n return provider;\r\n}\r\n\r\nexport function resolveLocalAuthentication(\r\n baseUrl: string,\r\n env: Record<string, string | undefined> = process.env,\r\n) {\r\n if (env.ROLINO_TOKEN) return { source: \"environment\" as const, tokenSet: null };\r\n const tokenSet = loadOAuthTokenSet(baseUrl, env);\r\n return tokenSet\r\n ? { source: \"oauth\" as const, tokenSet }\r\n : { source: \"none\" as const, tokenSet: null };\r\n}\r\n"],"mappings":"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","names":[]}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n chmodSync,\n existsSync,\n mkdirSync,\n readFileSync,\n renameSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport { normalizeRolinoBaseUrl } from \"@rolino/sdk\";\n\nexport const ROLINO_CLI_OAUTH_CLIENT_ID = \"rolino-cli\";\n\nexport type OAuthTokenSet = {\n host: string;\n issuer: string;\n clientId: string;\n resource: string;\n accessToken: string;\n accessTokenExpiresAt: string;\n refreshToken: string;\n refreshTokenExpiresAt: string;\n scopes: string[];\n};\n\ntype OAuthTokenStore = {\n version: 2;\n tokens: Record<string, OAuthTokenSet>;\n};\n\ntype RefreshableTokenProvider = (() => Promise<string | undefined>) & {\n refresh: () => Promise<string | undefined>;\n};\n\nconst refreshLocks = new Map<string, Promise<OAuthTokenSet>>();\n\nfunction defaultConfigDirectory(env: Record<string, string | undefined>) {\n if (env.ROLINO_CONFIG_DIR) return env.ROLINO_CONFIG_DIR;\n if (process.platform === \"win32\" && env.APPDATA) return join(env.APPDATA, \"Rolino\");\n if (process.platform === \"darwin\") return join(homedir(), \"Library\", \"Application Support\", \"Rolino\");\n return join(env.XDG_CONFIG_HOME ?? join(homedir(), \".config\"), \"rolino\");\n}\n\nexport function oauthTokenStorePath(\n env: Record<string, string | undefined> = process.env,\n) {\n return join(defaultConfigDirectory(env), \"oauth-tokens.json\");\n}\n\nexport function oauthConfiguration(baseUrl: string) {\n const host = normalizeRolinoBaseUrl(baseUrl);\n return {\n host,\n issuer: `${host}/api/auth`,\n clientId: ROLINO_CLI_OAUTH_CLIENT_ID,\n resource: `${host}/api/v1`,\n };\n}\n\nfunction tokenKey(input: Pick<OAuthTokenSet, \"host\" | \"issuer\" | \"clientId\" | \"resource\">) {\n return JSON.stringify([input.host, input.issuer, input.clientId, input.resource]);\n}\n\nfunction isTokenSet(value: unknown): value is OAuthTokenSet {\n if (!value || typeof value !== \"object\") return false;\n const token = value as Partial<OAuthTokenSet>;\n return [token.host, token.issuer, token.clientId, token.resource, token.accessToken,\n token.accessTokenExpiresAt, token.refreshToken, token.refreshTokenExpiresAt]\n .every((item) => typeof item === \"string\" && item.length > 0)\n && Array.isArray(token.scopes)\n && token.scopes.every((scope) => typeof scope === \"string\");\n}\n\nfunction readStore(env: Record<string, string | undefined>): OAuthTokenStore {\n const path = oauthTokenStorePath(env);\n if (!existsSync(path)) return { version: 2, tokens: {} };\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as Partial<OAuthTokenStore>;\n if (\n parsed.version !== 2\n || !parsed.tokens\n || typeof parsed.tokens !== \"object\"\n || !Object.values(parsed.tokens).every(isTokenSet)\n ) throw new Error(\"invalid\");\n return parsed as OAuthTokenStore;\n } catch {\n throw new TypeError(`Rolino could not read its OAuth token store at ${path}.`);\n }\n}\n\nfunction writeStore(store: OAuthTokenStore, env: Record<string, string | undefined>) {\n const path = oauthTokenStorePath(env);\n const temporary = `${path}.${process.pid}.tmp`;\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\n writeFileSync(temporary, `${JSON.stringify(store, null, 2)}\\n`, {\n encoding: \"utf8\",\n mode: 0o600,\n });\n chmodSync(temporary, 0o600);\n renameSync(temporary, path);\n chmodSync(path, 0o600);\n return path;\n}\n\nexport function loadOAuthTokenSet(\n baseUrl: string,\n env: Record<string, string | undefined> = process.env,\n) {\n const configuration = oauthConfiguration(baseUrl);\n return readStore(env).tokens[tokenKey(configuration)] ?? null;\n}\n\nexport function saveOAuthTokenSet(\n tokenSet: OAuthTokenSet,\n env: Record<string, string | undefined> = process.env,\n) {\n const configuration = oauthConfiguration(tokenSet.host);\n if (\n tokenSet.host !== configuration.host\n || tokenSet.issuer !== configuration.issuer\n || tokenSet.clientId !== configuration.clientId\n || tokenSet.resource !== configuration.resource\n ) throw new TypeError(\"The OAuth token set does not match the Rolino host.\");\n const store = readStore(env);\n store.tokens[tokenKey(tokenSet)] = tokenSet;\n const path = writeStore(store, env);\n const retiredInteractiveCredential = join(defaultConfigDirectory(env), \"credentials.json\");\n if (existsSync(retiredInteractiveCredential)) unlinkSync(retiredInteractiveCredential);\n return path;\n}\n\nexport function clearOAuthTokenSet(\n baseUrl: string,\n env: Record<string, string | undefined> = process.env,\n) {\n const path = oauthTokenStorePath(env);\n const store = readStore(env);\n const key = tokenKey(oauthConfiguration(baseUrl));\n const existed = Boolean(store.tokens[key]);\n delete store.tokens[key];\n if (!Object.keys(store.tokens).length) {\n if (existsSync(path)) unlinkSync(path);\n } else {\n writeStore(store, env);\n }\n return existed;\n}\n\nasync function refreshOAuthTokenSet(options: {\n baseUrl: string;\n env: Record<string, string | undefined>;\n fetch: typeof globalThis.fetch;\n}) {\n const current = loadOAuthTokenSet(options.baseUrl, options.env);\n if (!current) throw new TypeError(\"OAuth sign-in is required. Run `rolino auth login`.\");\n const key = tokenKey(current);\n const existing = refreshLocks.get(key);\n if (existing) return existing;\n\n const refresh = (async () => {\n const body = new URLSearchParams({\n grant_type: \"refresh_token\",\n refresh_token: current.refreshToken,\n client_id: current.clientId,\n resource: current.resource,\n });\n const response = await options.fetch(`${current.issuer}/oauth2/token`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/x-www-form-urlencoded\", accept: \"application/json\" },\n body,\n });\n const payload = await response.json().catch(() => null) as Record<string, unknown> | null;\n if (!response.ok || !payload || typeof payload.access_token !== \"string\") {\n throw new TypeError(\"OAuth sign-in is required. Run `rolino auth login`.\");\n }\n const expiresIn = typeof payload.expires_in === \"number\" ? payload.expires_in : 300;\n const refreshed: OAuthTokenSet = {\n ...current,\n accessToken: payload.access_token,\n accessTokenExpiresAt: new Date(Date.now() + expiresIn * 1_000).toISOString(),\n refreshToken: typeof payload.refresh_token === \"string\" ? payload.refresh_token : current.refreshToken,\n scopes: typeof payload.scope === \"string\" ? payload.scope.split(/\\s+/).filter(Boolean) : current.scopes,\n };\n saveOAuthTokenSet(refreshed, options.env);\n return refreshed;\n })().finally(() => refreshLocks.delete(key));\n refreshLocks.set(key, refresh);\n return refresh;\n}\n\nexport function createOAuthAccessTokenProvider(options: {\n baseUrl: string;\n env?: Record<string, string | undefined>;\n fetch?: typeof globalThis.fetch;\n}): RefreshableTokenProvider {\n const env = options.env ?? process.env;\n const fetchImplementation = options.fetch ?? globalThis.fetch;\n const obtain = async (force: boolean) => {\n if (env.ROLINO_TOKEN) return env.ROLINO_TOKEN;\n const token = loadOAuthTokenSet(options.baseUrl, env);\n if (!token) return undefined;\n if (!force && Date.parse(token.accessTokenExpiresAt) - Date.now() > 30_000) {\n return token.accessToken;\n }\n return (await refreshOAuthTokenSet({\n baseUrl: options.baseUrl,\n env,\n fetch: fetchImplementation,\n })).accessToken;\n };\n const provider = (() => obtain(false)) as RefreshableTokenProvider;\n provider.refresh = () => obtain(true);\n return provider;\n}\n\nexport function resolveLocalAuthentication(\n baseUrl: string,\n env: Record<string, string | undefined> = process.env,\n) {\n if (env.ROLINO_TOKEN) return { source: \"environment\" as const, tokenSet: null };\n const tokenSet = loadOAuthTokenSet(baseUrl, env);\n return tokenSet\n ? { source: \"oauth\" as const, tokenSet }\n : { source: \"none\" as const, tokenSet: null };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\r\n chmodSync,\r\n existsSync,\r\n mkdirSync,\r\n readFileSync,\r\n renameSync,\r\n unlinkSync,\r\n writeFileSync,\r\n} from \"node:fs\";\r\nimport { homedir } from \"node:os\";\r\nimport { dirname, join } from \"node:path\";\r\n\r\nimport { normalizeRolinoBaseUrl } from \"@rolino/sdk\";\r\n\r\nexport const ROLINO_CLI_OAUTH_CLIENT_ID = \"rolino-cli\";\r\n\r\nexport type OAuthTokenSet = {\r\n host: string;\r\n issuer: string;\r\n clientId: string;\r\n resource: string;\r\n accessToken: string;\r\n accessTokenExpiresAt: string;\r\n refreshToken: string;\r\n refreshTokenExpiresAt: string;\r\n scopes: string[];\r\n};\r\n\r\ntype OAuthTokenStore = {\r\n version: 2;\r\n tokens: Record<string, OAuthTokenSet>;\r\n};\r\n\r\ntype RefreshableTokenProvider = (() => Promise<string | undefined>) & {\r\n refresh: () => Promise<string | undefined>;\r\n};\r\n\r\nconst refreshLocks = new Map<string, Promise<OAuthTokenSet>>();\r\n\r\nfunction defaultConfigDirectory(env: Record<string, string | undefined>) {\r\n if (env.ROLINO_CONFIG_DIR) return env.ROLINO_CONFIG_DIR;\r\n if (process.platform === \"win32\" && env.APPDATA) return join(env.APPDATA, \"Rolino\");\r\n if (process.platform === \"darwin\") return join(homedir(), \"Library\", \"Application Support\", \"Rolino\");\r\n return join(env.XDG_CONFIG_HOME ?? join(homedir(), \".config\"), \"rolino\");\r\n}\r\n\r\nexport function oauthTokenStorePath(\r\n env: Record<string, string | undefined> = process.env,\r\n) {\r\n return join(defaultConfigDirectory(env), \"oauth-tokens.json\");\r\n}\r\n\r\nexport function oauthConfiguration(baseUrl: string) {\r\n const host = normalizeRolinoBaseUrl(baseUrl);\r\n return {\r\n host,\r\n issuer: `${host}/api/auth`,\r\n clientId: ROLINO_CLI_OAUTH_CLIENT_ID,\r\n resource: `${host}/api/v1`,\r\n };\r\n}\r\n\r\nfunction tokenKey(input: Pick<OAuthTokenSet, \"host\" | \"issuer\" | \"clientId\" | \"resource\">) {\r\n return JSON.stringify([input.host, input.issuer, input.clientId, input.resource]);\r\n}\r\n\r\nfunction isTokenSet(value: unknown): value is OAuthTokenSet {\r\n if (!value || typeof value !== \"object\") return false;\r\n const token = value as Partial<OAuthTokenSet>;\r\n return [token.host, token.issuer, token.clientId, token.resource, token.accessToken,\r\n token.accessTokenExpiresAt, token.refreshToken, token.refreshTokenExpiresAt]\r\n .every((item) => typeof item === \"string\" && item.length > 0)\r\n && Array.isArray(token.scopes)\r\n && token.scopes.every((scope) => typeof scope === \"string\");\r\n}\r\n\r\nfunction readStore(env: Record<string, string | undefined>): OAuthTokenStore {\r\n const path = oauthTokenStorePath(env);\r\n if (!existsSync(path)) return { version: 2, tokens: {} };\r\n try {\r\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as Partial<OAuthTokenStore>;\r\n if (\r\n parsed.version !== 2\r\n || !parsed.tokens\r\n || typeof parsed.tokens !== \"object\"\r\n || !Object.values(parsed.tokens).every(isTokenSet)\r\n ) throw new Error(\"invalid\");\r\n return parsed as OAuthTokenStore;\r\n } catch {\r\n throw new TypeError(`Rolino could not read its OAuth token store at ${path}.`);\r\n }\r\n}\r\n\r\nfunction writeStore(store: OAuthTokenStore, env: Record<string, string | undefined>) {\r\n const path = oauthTokenStorePath(env);\r\n const temporary = `${path}.${process.pid}.tmp`;\r\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\r\n writeFileSync(temporary, `${JSON.stringify(store, null, 2)}\\n`, {\r\n encoding: \"utf8\",\r\n mode: 0o600,\r\n });\r\n chmodSync(temporary, 0o600);\r\n renameSync(temporary, path);\r\n chmodSync(path, 0o600);\r\n return path;\r\n}\r\n\r\nexport function loadOAuthTokenSet(\r\n baseUrl: string,\r\n env: Record<string, string | undefined> = process.env,\r\n) {\r\n const configuration = oauthConfiguration(baseUrl);\r\n return readStore(env).tokens[tokenKey(configuration)] ?? null;\r\n}\r\n\r\nexport function saveOAuthTokenSet(\r\n tokenSet: OAuthTokenSet,\r\n env: Record<string, string | undefined> = process.env,\r\n) {\r\n const configuration = oauthConfiguration(tokenSet.host);\r\n if (\r\n tokenSet.host !== configuration.host\r\n || tokenSet.issuer !== configuration.issuer\r\n || tokenSet.clientId !== configuration.clientId\r\n || tokenSet.resource !== configuration.resource\r\n ) throw new TypeError(\"The OAuth token set does not match the Rolino host.\");\r\n const store = readStore(env);\r\n store.tokens[tokenKey(tokenSet)] = tokenSet;\r\n const path = writeStore(store, env);\r\n const retiredInteractiveCredential = join(defaultConfigDirectory(env), \"credentials.json\");\r\n if (existsSync(retiredInteractiveCredential)) unlinkSync(retiredInteractiveCredential);\r\n return path;\r\n}\r\n\r\nexport function clearOAuthTokenSet(\r\n baseUrl: string,\r\n env: Record<string, string | undefined> = process.env,\r\n) {\r\n const path = oauthTokenStorePath(env);\r\n const store = readStore(env);\r\n const key = tokenKey(oauthConfiguration(baseUrl));\r\n const existed = Boolean(store.tokens[key]);\r\n delete store.tokens[key];\r\n if (!Object.keys(store.tokens).length) {\r\n if (existsSync(path)) unlinkSync(path);\r\n } else {\r\n writeStore(store, env);\r\n }\r\n return existed;\r\n}\r\n\r\nasync function refreshOAuthTokenSet(options: {\r\n baseUrl: string;\r\n env: Record<string, string | undefined>;\r\n fetch: typeof globalThis.fetch;\r\n}) {\r\n const current = loadOAuthTokenSet(options.baseUrl, options.env);\r\n if (!current) throw new TypeError(\"OAuth sign-in is required. Run `rolino auth login`.\");\r\n const key = tokenKey(current);\r\n const existing = refreshLocks.get(key);\r\n if (existing) return existing;\r\n\r\n const refresh = (async () => {\r\n const body = new URLSearchParams({\r\n grant_type: \"refresh_token\",\r\n refresh_token: current.refreshToken,\r\n client_id: current.clientId,\r\n resource: current.resource,\r\n });\r\n const response = await options.fetch(`${current.issuer}/oauth2/token`, {\r\n method: \"POST\",\r\n headers: { \"content-type\": \"application/x-www-form-urlencoded\", accept: \"application/json\" },\r\n body,\r\n });\r\n const payload = await response.json().catch(() => null) as Record<string, unknown> | null;\r\n if (!response.ok || !payload || typeof payload.access_token !== \"string\") {\r\n throw new TypeError(\"OAuth sign-in is required. Run `rolino auth login`.\");\r\n }\r\n const expiresIn = typeof payload.expires_in === \"number\" ? payload.expires_in : 300;\r\n const refreshed: OAuthTokenSet = {\r\n ...current,\r\n accessToken: payload.access_token,\r\n accessTokenExpiresAt: new Date(Date.now() + expiresIn * 1_000).toISOString(),\r\n refreshToken: typeof payload.refresh_token === \"string\" ? payload.refresh_token : current.refreshToken,\r\n scopes: typeof payload.scope === \"string\" ? payload.scope.split(/\\s+/).filter(Boolean) : current.scopes,\r\n };\r\n saveOAuthTokenSet(refreshed, options.env);\r\n return refreshed;\r\n })().finally(() => refreshLocks.delete(key));\r\n refreshLocks.set(key, refresh);\r\n return refresh;\r\n}\r\n\r\nexport function createOAuthAccessTokenProvider(options: {\r\n baseUrl: string;\r\n env?: Record<string, string | undefined>;\r\n fetch?: typeof globalThis.fetch;\r\n}): RefreshableTokenProvider {\r\n const env = options.env ?? process.env;\r\n const fetchImplementation = options.fetch ?? globalThis.fetch;\r\n const obtain = async (force: boolean) => {\r\n if (env.ROLINO_TOKEN) return env.ROLINO_TOKEN;\r\n const token = loadOAuthTokenSet(options.baseUrl, env);\r\n if (!token) return undefined;\r\n if (!force && Date.parse(token.accessTokenExpiresAt) - Date.now() > 30_000) {\r\n return token.accessToken;\r\n }\r\n return (await refreshOAuthTokenSet({\r\n baseUrl: options.baseUrl,\r\n env,\r\n fetch: fetchImplementation,\r\n })).accessToken;\r\n };\r\n const provider = (() => obtain(false)) as RefreshableTokenProvider;\r\n provider.refresh = () => obtain(true);\r\n return provider;\r\n}\r\n\r\nexport function resolveLocalAuthentication(\r\n baseUrl: string,\r\n env: Record<string, string | undefined> = process.env,\r\n) {\r\n if (env.ROLINO_TOKEN) return { source: \"environment\" as const, tokenSet: null };\r\n const tokenSet = loadOAuthTokenSet(baseUrl, env);\r\n return tokenSet\r\n ? { source: \"oauth\" as const, tokenSet }\r\n : { source: \"none\" as const, tokenSet: null };\r\n}\r\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,eAAe;AACxB,SAAS,SAAS,YAAY;AAE9B,SAAS,8BAA8B;AAEhC,IAAM,6BAA6B;AAuB1C,IAAM,eAAe,oBAAI,IAAoC;AAE7D,SAAS,uBAAuB,KAAyC;AACvE,MAAI,IAAI,kBAAmB,QAAO,IAAI;AACtC,MAAI,QAAQ,aAAa,WAAW,IAAI,QAAS,QAAO,KAAK,IAAI,SAAS,QAAQ;AAClF,MAAI,QAAQ,aAAa,SAAU,QAAO,KAAK,QAAQ,GAAG,WAAW,uBAAuB,QAAQ;AACpG,SAAO,KAAK,IAAI,mBAAmB,KAAK,QAAQ,GAAG,SAAS,GAAG,QAAQ;AACzE;AAEO,SAAS,oBACd,MAA0C,QAAQ,KAClD;AACA,SAAO,KAAK,uBAAuB,GAAG,GAAG,mBAAmB;AAC9D;AAEO,SAAS,mBAAmB,SAAiB;AAClD,QAAM,OAAO,uBAAuB,OAAO;AAC3C,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,GAAG,IAAI;AAAA,IACf,UAAU;AAAA,IACV,UAAU,GAAG,IAAI;AAAA,EACnB;AACF;AAEA,SAAS,SAAS,OAAyE;AACzF,SAAO,KAAK,UAAU,CAAC,MAAM,MAAM,MAAM,QAAQ,MAAM,UAAU,MAAM,QAAQ,CAAC;AAClF;AAEA,SAAS,WAAW,OAAwC;AAC1D,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,QAAM,QAAQ;AACd,SAAO;AAAA,IAAC,MAAM;AAAA,IAAM,MAAM;AAAA,IAAQ,MAAM;AAAA,IAAU,MAAM;AAAA,IAAU,MAAM;AAAA,IACtE,MAAM;AAAA,IAAsB,MAAM;AAAA,IAAc,MAAM;AAAA,EAAqB,EAC1E,MAAM,CAAC,SAAS,OAAO,SAAS,YAAY,KAAK,SAAS,CAAC,KACzD,MAAM,QAAQ,MAAM,MAAM,KAC1B,MAAM,OAAO,MAAM,CAAC,UAAU,OAAO,UAAU,QAAQ;AAC9D;AAEA,SAAS,UAAU,KAA0D;AAC3E,QAAM,OAAO,oBAAoB,GAAG;AACpC,MAAI,CAAC,WAAW,IAAI,EAAG,QAAO,EAAE,SAAS,GAAG,QAAQ,CAAC,EAAE;AACvD,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,aAAa,MAAM,MAAM,CAAC;AACpD,QACE,OAAO,YAAY,KAChB,CAAC,OAAO,UACR,OAAO,OAAO,WAAW,YACzB,CAAC,OAAO,OAAO,OAAO,MAAM,EAAE,MAAM,UAAU,EACjD,OAAM,IAAI,MAAM,SAAS;AAC3B,WAAO;AAAA,EACT,QAAQ;AACN,UAAM,IAAI,UAAU,kDAAkD,IAAI,GAAG;AAAA,EAC/E;AACF;AAEA,SAAS,WAAW,OAAwB,KAAyC;AACnF,QAAM,OAAO,oBAAoB,GAAG;AACpC,QAAM,YAAY,GAAG,IAAI,IAAI,QAAQ,GAAG;AACxC,YAAU,QAAQ,IAAI,GAAG,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AACzD,gBAAc,WAAW,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AAAA,GAAM;AAAA,IAC9D,UAAU;AAAA,IACV,MAAM;AAAA,EACR,CAAC;AACD,YAAU,WAAW,GAAK;AAC1B,aAAW,WAAW,IAAI;AAC1B,YAAU,MAAM,GAAK;AACrB,SAAO;AACT;AAEO,SAAS,kBACd,SACA,MAA0C,QAAQ,KAClD;AACA,QAAM,gBAAgB,mBAAmB,OAAO;AAChD,SAAO,UAAU,GAAG,EAAE,OAAO,SAAS,aAAa,CAAC,KAAK;AAC3D;AAEO,SAAS,kBACd,UACA,MAA0C,QAAQ,KAClD;AACA,QAAM,gBAAgB,mBAAmB,SAAS,IAAI;AACtD,MACE,SAAS,SAAS,cAAc,QAC7B,SAAS,WAAW,cAAc,UAClC,SAAS,aAAa,cAAc,YACpC,SAAS,aAAa,cAAc,SACvC,OAAM,IAAI,UAAU,qDAAqD;AAC3E,QAAM,QAAQ,UAAU,GAAG;AAC3B,QAAM,OAAO,SAAS,QAAQ,CAAC,IAAI;AACnC,QAAM,OAAO,WAAW,OAAO,GAAG;AAClC,QAAM,+BAA+B,KAAK,uBAAuB,GAAG,GAAG,kBAAkB;AACzF,MAAI,WAAW,4BAA4B,EAAG,YAAW,4BAA4B;AACrF,SAAO;AACT;AAEO,SAAS,mBACd,SACA,MAA0C,QAAQ,KAClD;AACA,QAAM,OAAO,oBAAoB,GAAG;AACpC,QAAM,QAAQ,UAAU,GAAG;AAC3B,QAAM,MAAM,SAAS,mBAAmB,OAAO,CAAC;AAChD,QAAM,UAAU,QAAQ,MAAM,OAAO,GAAG,CAAC;AACzC,SAAO,MAAM,OAAO,GAAG;AACvB,MAAI,CAAC,OAAO,KAAK,MAAM,MAAM,EAAE,QAAQ;AACrC,QAAI,WAAW,IAAI,EAAG,YAAW,IAAI;AAAA,EACvC,OAAO;AACL,eAAW,OAAO,GAAG;AAAA,EACvB;AACA,SAAO;AACT;AAEA,eAAe,qBAAqB,SAIjC;AACD,QAAM,UAAU,kBAAkB,QAAQ,SAAS,QAAQ,GAAG;AAC9D,MAAI,CAAC,QAAS,OAAM,IAAI,UAAU,qDAAqD;AACvF,QAAM,MAAM,SAAS,OAAO;AAC5B,QAAM,WAAW,aAAa,IAAI,GAAG;AACrC,MAAI,SAAU,QAAO;AAErB,QAAM,WAAW,YAAY;AAC3B,UAAM,OAAO,IAAI,gBAAgB;AAAA,MAC/B,YAAY;AAAA,MACZ,eAAe,QAAQ;AAAA,MACvB,WAAW,QAAQ;AAAA,MACnB,UAAU,QAAQ;AAAA,IACpB,CAAC;AACD,UAAM,WAAW,MAAM,QAAQ,MAAM,GAAG,QAAQ,MAAM,iBAAiB;AAAA,MACrE,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,qCAAqC,QAAQ,mBAAmB;AAAA,MAC3F;AAAA,IACF,CAAC;AACD,UAAM,UAAU,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,IAAI;AACtD,QAAI,CAAC,SAAS,MAAM,CAAC,WAAW,OAAO,QAAQ,iBAAiB,UAAU;AACxE,YAAM,IAAI,UAAU,qDAAqD;AAAA,IAC3E;AACA,UAAM,YAAY,OAAO,QAAQ,eAAe,WAAW,QAAQ,aAAa;AAChF,UAAM,YAA2B;AAAA,MAC/B,GAAG;AAAA,MACH,aAAa,QAAQ;AAAA,MACrB,sBAAsB,IAAI,KAAK,KAAK,IAAI,IAAI,YAAY,GAAK,EAAE,YAAY;AAAA,MAC3E,cAAc,OAAO,QAAQ,kBAAkB,WAAW,QAAQ,gBAAgB,QAAQ;AAAA,MAC1F,QAAQ,OAAO,QAAQ,UAAU,WAAW,QAAQ,MAAM,MAAM,KAAK,EAAE,OAAO,OAAO,IAAI,QAAQ;AAAA,IACnG;AACA,sBAAkB,WAAW,QAAQ,GAAG;AACxC,WAAO;AAAA,EACT,GAAG,EAAE,QAAQ,MAAM,aAAa,OAAO,GAAG,CAAC;AAC3C,eAAa,IAAI,KAAK,OAAO;AAC7B,SAAO;AACT;AAEO,SAAS,+BAA+B,SAIlB;AAC3B,QAAM,MAAM,QAAQ,OAAO,QAAQ;AACnC,QAAM,sBAAsB,QAAQ,SAAS,WAAW;AACxD,QAAM,SAAS,OAAO,UAAmB;AACvC,QAAI,IAAI,aAAc,QAAO,IAAI;AACjC,UAAM,QAAQ,kBAAkB,QAAQ,SAAS,GAAG;AACpD,QAAI,CAAC,MAAO,QAAO;AACnB,QAAI,CAAC,SAAS,KAAK,MAAM,MAAM,oBAAoB,IAAI,KAAK,IAAI,IAAI,KAAQ;AAC1E,aAAO,MAAM;AAAA,IACf;AACA,YAAQ,MAAM,qBAAqB;AAAA,MACjC,SAAS,QAAQ;AAAA,MACjB;AAAA,MACA,OAAO;AAAA,IACT,CAAC,GAAG;AAAA,EACN;AACA,QAAM,YAAY,MAAM,OAAO,KAAK;AACpC,WAAS,UAAU,MAAM,OAAO,IAAI;AACpC,SAAO;AACT;AAEO,SAAS,2BACd,SACA,MAA0C,QAAQ,KAClD;AACA,MAAI,IAAI,aAAc,QAAO,EAAE,QAAQ,eAAwB,UAAU,KAAK;AAC9E,QAAM,WAAW,kBAAkB,SAAS,GAAG;AAC/C,SAAO,WACH,EAAE,QAAQ,SAAkB,SAAS,IACrC,EAAE,QAAQ,QAAiB,UAAU,KAAK;AAChD;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rolino/local-auth",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "Host-scoped local credential storage shared by Rolino's Node.js adapters",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"typecheck": "tsc --noEmit"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@rolino/sdk": "0.
|
|
57
|
+
"@rolino/sdk": "0.7.1"
|
|
58
58
|
},
|
|
59
59
|
"engines": {
|
|
60
60
|
"node": ">=20.19.0"
|