UNPKG

@azure/msal-node-extensions

Version:

![npm (scoped)](https://img.shields.io/npm/v/@azure/msal-node-extensions) ![npm](https://img.shields.io/npm/dw/@azure/msal-node-extensions)

100 lines (97 loc) 4.1 kB
/*! @azure/msal-node-extensions v1.5.9 2025-03-25 */ 'use strict'; import { CrossPlatformLock } from '../lock/CrossPlatformLock.mjs'; import { pid } from 'process'; /* * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. */ /** * MSAL cache plugin which enables callers to write the MSAL cache to disk on Windows, * macOs, and Linux. * * - Persistence can be one of: * - FilePersistence: Writes and reads from an unencrypted file. Can be used on Windows, * macOs, or Linux. * - FilePersistenceWithDataProtection: Used on Windows, writes and reads from file encrypted * with windows dpapi-addon. * - KeychainPersistence: Used on macOs, writes and reads from keychain. * - LibSecretPersistence: Used on linux, writes and reads from secret service API. Requires * libsecret be installed. */ class PersistenceCachePlugin { constructor(persistence, lockOptions) { this.persistence = persistence; // initialize logger this.logger = persistence.getLogger(); // create file lock this.lockFilePath = `${this.persistence.getFilePath()}.lockfile`; this.crossPlatformLock = new CrossPlatformLock(this.lockFilePath, this.logger, lockOptions); // initialize default values this.lastSync = 0; this.currentCache = null; } /** * Reads from storage and saves an in-memory copy. If persistence has not been updated * since last time data was read, in memory copy is used. * * If cacheContext.cacheHasChanged === true, then file lock is created and not deleted until * afterCacheAccess() is called, to prevent the cache file from changing in between * beforeCacheAccess() and afterCacheAccess(). */ async beforeCacheAccess(cacheContext) { this.logger.info("Executing before cache access"); const reloadNecessary = await this.persistence.reloadNecessary(this.lastSync); if (!reloadNecessary && this.currentCache !== null) { if (cacheContext.cacheHasChanged) { this.logger.verbose("Cache context has changed"); await this.crossPlatformLock.lock(); } return; } try { this.logger.info(`Reload necessary. Last sync time: ${this.lastSync}`); await this.crossPlatformLock.lock(); this.currentCache = await this.persistence.load(); this.lastSync = new Date().getTime(); if (this.currentCache) { cacheContext.tokenCache.deserialize(this.currentCache); } else { this.logger.info("Cache empty."); } this.logger.info(`Last sync time updated to: ${this.lastSync}`); } finally { if (!cacheContext.cacheHasChanged) { await this.crossPlatformLock.unlock(); this.logger.info(`Pid ${pid} released lock`); } else { this.logger.info(`Pid ${pid} beforeCacheAccess did not release lock`); } } } /** * Writes to storage if MSAL in memory copy of cache has been changed. */ async afterCacheAccess(cacheContext) { this.logger.info("Executing after cache access"); try { if (cacheContext.cacheHasChanged) { this.logger.info("Msal in-memory cache has changed. Writing changes to persistence"); this.currentCache = cacheContext.tokenCache.serialize(); await this.persistence.save(this.currentCache); } else { this.logger.info("Msal in-memory cache has not changed. Did not write to persistence"); } } finally { await this.crossPlatformLock.unlock(); this.logger.info(`Pid ${pid} afterCacheAccess released lock`); } } } export { PersistenceCachePlugin }; //# sourceMappingURL=PersistenceCachePlugin.mjs.map