diff --git a/src/azure/pca-auth.js b/src/azure/pca-auth.js index d938c84..8c237e7 100644 --- a/src/azure/pca-auth.js +++ b/src/azure/pca-auth.js @@ -1,5 +1,6 @@ import open, { apps } from "open"; +import fs from "node:fs"; import path from "node:path"; import { PublicClientApplication } from "@azure/msal-node"; @@ -10,20 +11,42 @@ import { PersistenceCreator, } from "@azure/msal-node-extensions"; +function fileCachePlugin(cachePath) { + return { + beforeCacheAccess: async (ctx) => { + if (fs.existsSync(cachePath)) { + ctx.tokenCache.deserialize(fs.readFileSync(cachePath, "utf8")); + } + }, + afterCacheAccess: async (ctx) => { + if (!ctx.cacheHasChanged) return; + fs.mkdirSync(path.dirname(cachePath), { recursive: true }); + fs.writeFileSync(cachePath, ctx.tokenCache.serialize()); + fs.chmodSync(cachePath, 0o600); + }, + }; +} + async function createPca({ tenantId, clientId }) { const cacheRoot = Environment.isWindowsPlatform() ? path.join(Environment.getUserRootDirectory(), "sk-az-tools") : path.join(Environment.getUserRootDirectory(), ".config", "sk-az-tools"); const cachePath = path.join(cacheRoot, `${clientId}-msal.cache`); - - const persistence = await PersistenceCreator.createPersistence({ - cachePath, - dataProtectionScope: DataProtectionScope.CurrentUser, - serviceName: "sk-az-tools", - accountName: "msal-cache", - usePlaintextFileOnLinux: true, - }); + let cachePlugin; + try { + const persistence = await PersistenceCreator.createPersistence({ + cachePath, + dataProtectionScope: DataProtectionScope.CurrentUser, + serviceName: "sk-az-tools", + accountName: "msal-cache", + usePlaintextFileOnLinux: true, + }); + cachePlugin = new PersistenceCachePlugin(persistence); + } catch (err) { + // Fallback for Linux environments where libsecret integration is unavailable. + cachePlugin = fileCachePlugin(cachePath); + } return new PublicClientApplication({ auth: { @@ -31,7 +54,7 @@ async function createPca({ tenantId, clientId }) { authority: `https://login.microsoftonline.com/${tenantId}`, }, cache: { - cachePlugin: new PersistenceCachePlugin(persistence), + cachePlugin, }, }); }