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)

91 lines (88 loc) 3.55 kB
/*! @azure/msal-node-extensions v1.5.9 2025-03-25 */ 'use strict'; import { FilePersistence } from './FilePersistence.mjs'; import { PersistenceError } from '../error/PersistenceError.mjs'; import { Dpapi } from '../Dpapi.mjs'; import { DataProtectionScope } from './DataProtectionScope.mjs'; import { dirname } from 'path'; import { BasePersistence } from './BasePersistence.mjs'; import { isNodeError } from '../utils/TypeGuards.mjs'; /* * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. */ /** * Uses CryptProtectData and CryptUnprotectData on Windows to encrypt and decrypt file contents. * * scope: Scope of the data protection. Either local user or the current machine * optionalEntropy: Password or other additional entropy used to encrypt the data */ class FilePersistenceWithDataProtection extends BasePersistence { constructor(filePersistence, scope, optionalEntropy) { super(); this.scope = scope; this.optionalEntropy = optionalEntropy ? Buffer.from(optionalEntropy, "utf-8") : null; this.filePersistence = filePersistence; } static async create(fileLocation, scope, optionalEntropy, loggerOptions) { const filePersistence = await FilePersistence.create(fileLocation, loggerOptions); const persistence = new FilePersistenceWithDataProtection(filePersistence, scope, optionalEntropy); return persistence; } async save(contents) { try { const encryptedContents = Dpapi.protectData(Buffer.from(contents, "utf-8"), this.optionalEntropy, this.scope.toString()); await this.filePersistence.saveBuffer(encryptedContents); } catch (err) { if (isNodeError(err)) { throw PersistenceError.createFilePersistenceWithDPAPIError(err.message); } else { throw err; } } } async load() { try { const encryptedContents = await this.filePersistence.loadBuffer(); if (typeof encryptedContents === "undefined" || !encryptedContents || 0 === encryptedContents.length) { this.filePersistence .getLogger() .info("Encrypted contents loaded from file were null or empty"); return null; } return Dpapi.unprotectData(encryptedContents, this.optionalEntropy, this.scope.toString()).toString(); } catch (err) { if (isNodeError(err)) { throw PersistenceError.createFilePersistenceWithDPAPIError(err.message); } else { throw err; } } } async delete() { return this.filePersistence.delete(); } async reloadNecessary(lastSync) { return this.filePersistence.reloadNecessary(lastSync); } getFilePath() { return this.filePersistence.getFilePath(); } getLogger() { return this.filePersistence.getLogger(); } createForPersistenceValidation() { const testCacheFileLocation = `${dirname(this.filePersistence.getFilePath())}/test.cache`; return FilePersistenceWithDataProtection.create(testCacheFileLocation, DataProtectionScope.CurrentUser); } } export { FilePersistenceWithDataProtection }; //# sourceMappingURL=FilePersistenceWithDataProtection.mjs.map