@equinor/fusion-framework-cli 11.0.0-next.8 → 11.0.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 +71 -94
- package/README.md +98 -104
- package/bin/build/bin.mjs +1 -0
- package/bin/build/cli.mjs +7 -0
- package/bin/cli.mjs +1 -1
- package/dist/esm/lib/app/app-config.js.map +1 -1
- package/dist/esm/lib/app/app-manifest.js.map +1 -1
- package/dist/esm/lib/app/app-package.js +1 -1
- package/dist/esm/lib/app/app-package.js.map +1 -1
- package/dist/esm/lib/app/merge-app-config.js +11 -5
- package/dist/esm/lib/app/merge-app-config.js.map +1 -1
- package/dist/esm/lib/app/merge-app-manifest.js +2 -2
- package/dist/esm/lib/app/merge-app-manifest.js.map +1 -1
- package/dist/esm/lib/index.js +3 -1
- package/dist/esm/lib/index.js.map +1 -1
- package/dist/esm/lib/load-dev-server-config.js +7 -3
- package/dist/esm/lib/load-dev-server-config.js.map +1 -1
- package/dist/esm/lib/merge-dev-server-config.js +24 -16
- package/dist/esm/lib/merge-dev-server-config.js.map +1 -1
- package/dist/esm/lib/portal/create-portal-manifest.js.map +1 -1
- package/dist/esm/lib/portal/load-portal-config.js +1 -1
- package/dist/esm/lib/portal/load-portal-config.js.map +1 -1
- package/dist/esm/lib/portal/load-portal-manifest.js +8 -4
- package/dist/esm/lib/portal/load-portal-manifest.js.map +1 -1
- package/dist/esm/lib/portal/load-portal-schema.js.map +1 -1
- package/dist/esm/lib/portal/portal-config.js.map +1 -1
- package/dist/esm/lib/utils/index.js +1 -0
- package/dist/esm/lib/utils/index.js.map +1 -1
- package/dist/esm/lib/utils/resolve-annotations.js +48 -5
- package/dist/esm/lib/utils/resolve-annotations.js.map +1 -1
- package/dist/esm/lib/utils/resolve-devops-annotations.js +7 -3
- package/dist/esm/lib/utils/resolve-devops-annotations.js.map +1 -1
- package/dist/esm/lib/utils/resolve-git-commit-sha.js +1 -0
- package/dist/esm/lib/utils/resolve-git-commit-sha.js.map +1 -1
- package/dist/esm/lib/utils/resolve-github-annotations.js +16 -72
- package/dist/esm/lib/utils/resolve-github-annotations.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/types/bin/app-build.d.ts +2 -2
- package/dist/types/bin/app-check.d.ts +2 -2
- package/dist/types/bin/app-config-publish.d.ts +2 -2
- package/dist/types/bin/app-config.d.ts +3 -3
- package/dist/types/bin/app-dev.d.ts +1 -1
- package/dist/types/bin/app-manifest.d.ts +3 -3
- package/dist/types/bin/app-pack.d.ts +1 -1
- package/dist/types/bin/app-tag.d.ts +3 -3
- package/dist/types/bin/app-upload.d.ts +2 -2
- package/dist/types/bin/helpers/load-vite-config.d.ts +1 -2
- package/dist/types/bin/helpers/resolve-app-config.d.ts +3 -3
- package/dist/types/bin/helpers/resolve-app-manifest.d.ts +3 -3
- package/dist/types/bin/helpers/resolve-portal-config.d.ts +3 -3
- package/dist/types/bin/helpers/resolve-portal-manifest.d.ts +3 -4
- package/dist/types/bin/helpers/resolve-project-package.d.ts +2 -2
- package/dist/types/bin/index.d.ts +9 -0
- package/dist/types/bin/pack.d.ts +1 -1
- package/dist/types/bin/portal-build.d.ts +5 -5
- package/dist/types/bin/portal-config-publish.d.ts +2 -2
- package/dist/types/bin/portal-config.d.ts +4 -4
- package/dist/types/bin/portal-dev.d.ts +2 -2
- package/dist/types/bin/portal-manifest.d.ts +4 -4
- package/dist/types/bin/portal-pack.d.ts +3 -3
- package/dist/types/bin/portal-tag.d.ts +2 -2
- package/dist/types/bin/portal-upload.d.ts +2 -2
- package/dist/types/bin/utils/create-dev-server.d.ts +2 -2
- package/dist/types/cli/commands/disco/resolve.d.ts +1 -1
- package/dist/types/cli/main.d.ts +0 -20
- package/dist/types/cli/options/env.d.ts +1 -2
- package/dist/types/lib/app/app-config.d.ts +2 -2
- package/dist/types/lib/app/app-manifest.d.ts +1 -1
- package/dist/types/lib/app/merge-app-config.d.ts +1 -1
- package/dist/types/lib/app/merge-app-manifest.d.ts +1 -1
- package/dist/types/lib/index.d.ts +3 -2
- package/dist/types/lib/legacy.d.ts +1 -1
- package/dist/types/lib/load-dev-server-config.d.ts +2 -2
- package/dist/types/lib/merge-dev-server-config.d.ts +1 -1
- package/dist/types/lib/portal/create-portal-manifest.d.ts +1 -1
- package/dist/types/lib/portal/load-portal-manifest.d.ts +2 -2
- package/dist/types/lib/portal/load-portal-schema.d.ts +1 -1
- package/dist/types/lib/portal/portal-config.d.ts +2 -2
- package/dist/types/lib/portal/portal-manifest.schema.d.ts +6 -6
- package/dist/types/lib/types.d.ts +29 -0
- package/dist/types/lib/utils/index.d.ts +1 -0
- package/dist/types/lib/utils/resolve-annotations.d.ts +35 -1
- package/dist/types/lib/utils/resolve-devops-annotations.d.ts +28 -3
- package/dist/types/lib/utils/resolve-git-commit-sha.d.ts +1 -0
- package/dist/types/lib/utils/resolve-github-annotations.d.ts +85 -13
- package/dist/types/lib/utils/types.d.ts +57 -1
- package/dist/types/version.d.ts +1 -1
- package/docs/application.md +73 -79
- package/docs/auth.md +18 -45
- package/docs/libsecret.md +0 -31
- package/docs/migration-v10-to-v11.md +43 -47
- package/docs/portal.md +4 -38
- package/package.json +69 -33
- package/bin/build/bin.js +0 -28
- package/bin/build/cli.js +0 -10099
- package/bin/build/create-auth-client-B_j4Y_Dr.js +0 -1415
- package/bin/build/portal-config-publish-ezU_DFki.js +0 -29578
- package/dist/esm/bin/app-build.js +0 -34
- package/dist/esm/bin/app-build.js.map +0 -1
- package/dist/esm/bin/app-check.js +0 -63
- package/dist/esm/bin/app-check.js.map +0 -1
- package/dist/esm/bin/app-config-publish.js +0 -89
- package/dist/esm/bin/app-config-publish.js.map +0 -1
- package/dist/esm/bin/app-config.js +0 -48
- package/dist/esm/bin/app-config.js.map +0 -1
- package/dist/esm/bin/app-dev.js +0 -102
- package/dist/esm/bin/app-dev.js.map +0 -1
- package/dist/esm/bin/app-manifest.js +0 -38
- package/dist/esm/bin/app-manifest.js.map +0 -1
- package/dist/esm/bin/app-pack.js +0 -51
- package/dist/esm/bin/app-pack.js.map +0 -1
- package/dist/esm/bin/app-tag.js +0 -89
- package/dist/esm/bin/app-tag.js.map +0 -1
- package/dist/esm/bin/app-upload.js +0 -109
- package/dist/esm/bin/app-upload.js.map +0 -1
- package/dist/esm/bin/helpers/load-bundle-metadata.js +0 -32
- package/dist/esm/bin/helpers/load-bundle-metadata.js.map +0 -1
- package/dist/esm/bin/helpers/load-vite-config.js +0 -55
- package/dist/esm/bin/helpers/load-vite-config.js.map +0 -1
- package/dist/esm/bin/helpers/resolve-app-config.js +0 -46
- package/dist/esm/bin/helpers/resolve-app-config.js.map +0 -1
- package/dist/esm/bin/helpers/resolve-app-manifest.js +0 -55
- package/dist/esm/bin/helpers/resolve-app-manifest.js.map +0 -1
- package/dist/esm/bin/helpers/resolve-portal-config.js +0 -46
- package/dist/esm/bin/helpers/resolve-portal-config.js.map +0 -1
- package/dist/esm/bin/helpers/resolve-portal-manifest.js +0 -55
- package/dist/esm/bin/helpers/resolve-portal-manifest.js.map +0 -1
- package/dist/esm/bin/helpers/resolve-project-package.js +0 -32
- package/dist/esm/bin/helpers/resolve-project-package.js.map +0 -1
- package/dist/esm/bin/index.js +0 -12
- package/dist/esm/bin/index.js.map +0 -1
- package/dist/esm/bin/pack.js +0 -70
- package/dist/esm/bin/pack.js.map +0 -1
- package/dist/esm/bin/portal-build.js +0 -40
- package/dist/esm/bin/portal-build.js.map +0 -1
- package/dist/esm/bin/portal-config-publish.js +0 -74
- package/dist/esm/bin/portal-config-publish.js.map +0 -1
- package/dist/esm/bin/portal-config.js +0 -48
- package/dist/esm/bin/portal-config.js.map +0 -1
- package/dist/esm/bin/portal-dev.js +0 -61
- package/dist/esm/bin/portal-dev.js.map +0 -1
- package/dist/esm/bin/portal-manifest.js +0 -38
- package/dist/esm/bin/portal-manifest.js.map +0 -1
- package/dist/esm/bin/portal-pack.js +0 -60
- package/dist/esm/bin/portal-pack.js.map +0 -1
- package/dist/esm/bin/portal-tag.js +0 -96
- package/dist/esm/bin/portal-tag.js.map +0 -1
- package/dist/esm/bin/portal-upload.js +0 -99
- package/dist/esm/bin/portal-upload.js.map +0 -1
- package/dist/esm/bin/utils/ConsoleLogger.js +0 -112
- package/dist/esm/bin/utils/ConsoleLogger.js.map +0 -1
- package/dist/esm/bin/utils/create-dev-server.js +0 -167
- package/dist/esm/bin/utils/create-dev-server.js.map +0 -1
- package/dist/esm/bin/utils/format.js +0 -47
- package/dist/esm/bin/utils/format.js.map +0 -1
- package/dist/esm/bin/utils/index.js +0 -5
- package/dist/esm/bin/utils/index.js.map +0 -1
- package/dist/esm/bin/utils/spinner.js +0 -142
- package/dist/esm/bin/utils/spinner.js.map +0 -1
- package/dist/esm/cli/commands/app/alias.js +0 -42
- package/dist/esm/cli/commands/app/alias.js.map +0 -1
- package/dist/esm/cli/commands/app/build.js +0 -53
- package/dist/esm/cli/commands/app/build.js.map +0 -1
- package/dist/esm/cli/commands/app/check.js +0 -57
- package/dist/esm/cli/commands/app/check.js.map +0 -1
- package/dist/esm/cli/commands/app/config.js +0 -103
- package/dist/esm/cli/commands/app/config.js.map +0 -1
- package/dist/esm/cli/commands/app/dev.js +0 -67
- package/dist/esm/cli/commands/app/dev.js.map +0 -1
- package/dist/esm/cli/commands/app/index.js +0 -42
- package/dist/esm/cli/commands/app/index.js.map +0 -1
- package/dist/esm/cli/commands/app/manifest.js +0 -82
- package/dist/esm/cli/commands/app/manifest.js.map +0 -1
- package/dist/esm/cli/commands/app/pack.js +0 -71
- package/dist/esm/cli/commands/app/pack.js.map +0 -1
- package/dist/esm/cli/commands/app/publish.js +0 -130
- package/dist/esm/cli/commands/app/publish.js.map +0 -1
- package/dist/esm/cli/commands/app/tag.js +0 -113
- package/dist/esm/cli/commands/app/tag.js.map +0 -1
- package/dist/esm/cli/commands/app/upload.js +0 -85
- package/dist/esm/cli/commands/app/upload.js.map +0 -1
- package/dist/esm/cli/commands/auth/index.js +0 -22
- package/dist/esm/cli/commands/auth/index.js.map +0 -1
- package/dist/esm/cli/commands/auth/login.js +0 -72
- package/dist/esm/cli/commands/auth/login.js.map +0 -1
- package/dist/esm/cli/commands/auth/logout.js +0 -58
- package/dist/esm/cli/commands/auth/logout.js.map +0 -1
- package/dist/esm/cli/commands/auth/token.js +0 -78
- package/dist/esm/cli/commands/auth/token.js.map +0 -1
- package/dist/esm/cli/commands/disco/index.js +0 -6
- package/dist/esm/cli/commands/disco/index.js.map +0 -1
- package/dist/esm/cli/commands/disco/resolve.js +0 -58
- package/dist/esm/cli/commands/disco/resolve.js.map +0 -1
- package/dist/esm/cli/commands/index.js +0 -11
- package/dist/esm/cli/commands/index.js.map +0 -1
- package/dist/esm/cli/commands/portal/build.js +0 -27
- package/dist/esm/cli/commands/portal/build.js.map +0 -1
- package/dist/esm/cli/commands/portal/config.js +0 -101
- package/dist/esm/cli/commands/portal/config.js.map +0 -1
- package/dist/esm/cli/commands/portal/dev.js +0 -27
- package/dist/esm/cli/commands/portal/dev.js.map +0 -1
- package/dist/esm/cli/commands/portal/index.js +0 -23
- package/dist/esm/cli/commands/portal/index.js.map +0 -1
- package/dist/esm/cli/commands/portal/manifest.js +0 -48
- package/dist/esm/cli/commands/portal/manifest.js.map +0 -1
- package/dist/esm/cli/commands/portal/pack.js +0 -40
- package/dist/esm/cli/commands/portal/pack.js.map +0 -1
- package/dist/esm/cli/commands/portal/publish.js +0 -76
- package/dist/esm/cli/commands/portal/publish.js.map +0 -1
- package/dist/esm/cli/commands/portal/schema.js +0 -70
- package/dist/esm/cli/commands/portal/schema.js.map +0 -1
- package/dist/esm/cli/commands/portal/tag.js +0 -73
- package/dist/esm/cli/commands/portal/tag.js.map +0 -1
- package/dist/esm/cli/commands/portal/upload.js +0 -41
- package/dist/esm/cli/commands/portal/upload.js.map +0 -1
- package/dist/esm/cli/main.js +0 -52
- package/dist/esm/cli/main.js.map +0 -1
- package/dist/esm/cli/options/auth.js +0 -96
- package/dist/esm/cli/options/auth.js.map +0 -1
- package/dist/esm/cli/options/env.js +0 -30
- package/dist/esm/cli/options/env.js.map +0 -1
- package/dist/esm/lib/framework.node.js +0 -104
- package/dist/esm/lib/framework.node.js.map +0 -1
- package/dist/esm/version.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- /package/dist/types/{lib → bin}/framework.node.d.ts +0 -0
|
@@ -1,1415 +0,0 @@
|
|
|
1
|
-
import { P as PublicClientApplication } from './portal-config-publish-ezU_DFki.js';
|
|
2
|
-
import 'crypto';
|
|
3
|
-
import { promises } from 'fs';
|
|
4
|
-
import { pid } from 'process';
|
|
5
|
-
import path, { dirname } from 'path';
|
|
6
|
-
import { createRequire } from 'module';
|
|
7
|
-
import keytar from 'keytar';
|
|
8
|
-
import { tmpdir } from 'node:os';
|
|
9
|
-
import path$1 from 'node:path';
|
|
10
|
-
import 'vite';
|
|
11
|
-
import 'chalk';
|
|
12
|
-
import '@equinor/fusion-imports';
|
|
13
|
-
import '@equinor/fusion-framework-dev-server';
|
|
14
|
-
import 'node:fs';
|
|
15
|
-
import 'node:fs/promises';
|
|
16
|
-
import 'read-package-up';
|
|
17
|
-
import 'node:url';
|
|
18
|
-
import 'node:assert';
|
|
19
|
-
import 'node:child_process';
|
|
20
|
-
import 'zod';
|
|
21
|
-
import 'adm-zip';
|
|
22
|
-
import 'http';
|
|
23
|
-
import 'https';
|
|
24
|
-
import 'buffer';
|
|
25
|
-
import 'stream';
|
|
26
|
-
import 'util';
|
|
27
|
-
import 'node:http';
|
|
28
|
-
import 'node:process';
|
|
29
|
-
import 'node:buffer';
|
|
30
|
-
import 'node:util';
|
|
31
|
-
import 'ora';
|
|
32
|
-
|
|
33
|
-
/*! @azure/msal-node-extensions v1.5.13 2025-05-06 */
|
|
34
|
-
/*
|
|
35
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
36
|
-
* Licensed under the MIT License.
|
|
37
|
-
*/
|
|
38
|
-
const Constants$1 = {
|
|
39
|
-
/**
|
|
40
|
-
* An existing file was the target of an operation that required that the target not exist
|
|
41
|
-
*/
|
|
42
|
-
EEXIST_ERROR: "EEXIST",
|
|
43
|
-
/**
|
|
44
|
-
* No such file or directory: Commonly raised by fs operations to indicate that a component
|
|
45
|
-
* of the specified pathname does not exist. No entity (file or directory) could be found
|
|
46
|
-
* by the given path
|
|
47
|
-
*/
|
|
48
|
-
ENOENT_ERROR: "ENOENT",
|
|
49
|
-
/**
|
|
50
|
-
* Operation not permitted. An attempt was made to perform an operation that requires
|
|
51
|
-
* elevated privileges.
|
|
52
|
-
*/
|
|
53
|
-
EPERM_ERROR: "EPERM",
|
|
54
|
-
/**
|
|
55
|
-
* Default service name for using MSAL Keytar
|
|
56
|
-
*/
|
|
57
|
-
DEFAULT_SERVICE_NAME: "msal-node-extensions",
|
|
58
|
-
/**
|
|
59
|
-
* Test data used to verify underlying persistence mechanism
|
|
60
|
-
*/
|
|
61
|
-
PERSISTENCE_TEST_DATA: "Dummy data to verify underlying persistence mechanism",
|
|
62
|
-
/**
|
|
63
|
-
* This is the value of a the guid if the process is being ran by the root user
|
|
64
|
-
*/
|
|
65
|
-
LINUX_ROOT_USER_GUID: 0,
|
|
66
|
-
/**
|
|
67
|
-
* List of environment variables
|
|
68
|
-
*/
|
|
69
|
-
ENVIRONMENT: {
|
|
70
|
-
HOME: "HOME",
|
|
71
|
-
LOGNAME: "LOGNAME",
|
|
72
|
-
USER: "USER",
|
|
73
|
-
LNAME: "LNAME",
|
|
74
|
-
USERNAME: "USERNAME",
|
|
75
|
-
PLATFORM: "platform",
|
|
76
|
-
LOCAL_APPLICATION_DATA: "LOCALAPPDATA",
|
|
77
|
-
},
|
|
78
|
-
// Name of the default cache file
|
|
79
|
-
DEFAULT_CACHE_FILE_NAME: "cache.json",
|
|
80
|
-
};
|
|
81
|
-
const Platform = {
|
|
82
|
-
WINDOWS: "win32",
|
|
83
|
-
LINUX: "linux",
|
|
84
|
-
MACOS: "darwin",
|
|
85
|
-
};
|
|
86
|
-
const ErrorCodes = {
|
|
87
|
-
UNKNOWN: "unknown_error",
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
/*! @azure/msal-node-extensions v1.5.13 2025-05-06 */
|
|
91
|
-
/*
|
|
92
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
93
|
-
* Licensed under the MIT License.
|
|
94
|
-
*/
|
|
95
|
-
/**
|
|
96
|
-
* Error thrown when trying to write MSAL cache to persistence.
|
|
97
|
-
*/
|
|
98
|
-
class PersistenceError extends Error {
|
|
99
|
-
constructor(errorCode, errorMessage) {
|
|
100
|
-
const errorString = errorMessage
|
|
101
|
-
? `${errorCode}: ${errorMessage}`
|
|
102
|
-
: errorCode;
|
|
103
|
-
super(errorString);
|
|
104
|
-
Object.setPrototypeOf(this, PersistenceError.prototype);
|
|
105
|
-
this.errorCode = errorCode;
|
|
106
|
-
this.errorMessage = errorMessage;
|
|
107
|
-
this.name = "PersistenceError";
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Error thrown when trying to access the file system.
|
|
111
|
-
*/
|
|
112
|
-
static createFileSystemError(errorCode, errorMessage) {
|
|
113
|
-
return new PersistenceError(errorCode, errorMessage);
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Error thrown when trying to write, load, or delete data from secret service on linux.
|
|
117
|
-
* Libsecret is used to access secret service.
|
|
118
|
-
*/
|
|
119
|
-
static createLibSecretError(errorMessage) {
|
|
120
|
-
return new PersistenceError("GnomeKeyringError", errorMessage);
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Error thrown when trying to write, load, or delete data from keychain on macOs.
|
|
124
|
-
*/
|
|
125
|
-
static createKeychainPersistenceError(errorMessage) {
|
|
126
|
-
return new PersistenceError("KeychainError", errorMessage);
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Error thrown when trying to encrypt or decrypt data using DPAPI on Windows.
|
|
130
|
-
*/
|
|
131
|
-
static createFilePersistenceWithDPAPIError(errorMessage) {
|
|
132
|
-
return new PersistenceError("DPAPIEncryptedFileError", errorMessage);
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Error thrown when using the cross platform lock.
|
|
136
|
-
*/
|
|
137
|
-
static createCrossPlatformLockError(errorMessage) {
|
|
138
|
-
return new PersistenceError("CrossPlatformLockError", errorMessage);
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Throw cache persistence error
|
|
142
|
-
*
|
|
143
|
-
* @param errorMessage string
|
|
144
|
-
* @returns PersistenceError
|
|
145
|
-
*/
|
|
146
|
-
static createCachePersistenceError(errorMessage) {
|
|
147
|
-
return new PersistenceError("CachePersistenceError", errorMessage);
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Throw unsupported error
|
|
151
|
-
*
|
|
152
|
-
* @param errorMessage string
|
|
153
|
-
* @returns PersistenceError
|
|
154
|
-
*/
|
|
155
|
-
static createNotSupportedError(errorMessage) {
|
|
156
|
-
return new PersistenceError("NotSupportedError", errorMessage);
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Throw persistence not verified error
|
|
160
|
-
*
|
|
161
|
-
* @param errorMessage string
|
|
162
|
-
* @returns PersistenceError
|
|
163
|
-
*/
|
|
164
|
-
static createPersistenceNotVerifiedError(errorMessage) {
|
|
165
|
-
return new PersistenceError("PersistenceNotVerifiedError", errorMessage);
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Throw persistence creation validation error
|
|
169
|
-
*
|
|
170
|
-
* @param errorMessage string
|
|
171
|
-
* @returns PersistenceError
|
|
172
|
-
*/
|
|
173
|
-
static createPersistenceNotValidatedError(errorMessage) {
|
|
174
|
-
return new PersistenceError("PersistenceNotValidatedError", errorMessage);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/*! @azure/msal-node-extensions v1.5.13 2025-05-06 */
|
|
179
|
-
/*
|
|
180
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
181
|
-
* Licensed under the MIT License.
|
|
182
|
-
*/
|
|
183
|
-
/**
|
|
184
|
-
* Returns whether or not the given object is a Node.js error
|
|
185
|
-
*/
|
|
186
|
-
const isNodeError = (error) => {
|
|
187
|
-
return !!error && typeof error === "object" && error.hasOwnProperty("code");
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
/*! @azure/msal-node-extensions v1.5.13 2025-05-06 */
|
|
191
|
-
|
|
192
|
-
/*
|
|
193
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
194
|
-
* Licensed under the MIT License.
|
|
195
|
-
*/
|
|
196
|
-
/**
|
|
197
|
-
* Cross-process lock that works on all platforms.
|
|
198
|
-
*/
|
|
199
|
-
class CrossPlatformLock {
|
|
200
|
-
constructor(lockFilePath, logger, lockOptions) {
|
|
201
|
-
this.lockFilePath = lockFilePath;
|
|
202
|
-
this.retryNumber = lockOptions ? lockOptions.retryNumber : 500;
|
|
203
|
-
this.retryDelay = lockOptions ? lockOptions.retryDelay : 100;
|
|
204
|
-
this.logger = logger;
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* Locks cache from read or writes by creating file with same path and name as
|
|
208
|
-
* cache file but with .lockfile extension. If another process has already created
|
|
209
|
-
* the lockfile, will back off and retry based on configuration settings set by CrossPlatformLockOptions
|
|
210
|
-
*/
|
|
211
|
-
async lock() {
|
|
212
|
-
for (let tryCount = 0; tryCount < this.retryNumber; tryCount++) {
|
|
213
|
-
try {
|
|
214
|
-
this.logger.info(`Pid ${pid} trying to acquire lock`);
|
|
215
|
-
this.lockFileHandle = await promises.open(this.lockFilePath, "wx+");
|
|
216
|
-
this.logger.info(`Pid ${pid} acquired lock`);
|
|
217
|
-
await this.lockFileHandle.write(pid.toString());
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
catch (err) {
|
|
221
|
-
if (isNodeError(err)) {
|
|
222
|
-
if (err.code === Constants$1.EEXIST_ERROR ||
|
|
223
|
-
err.code === Constants$1.EPERM_ERROR) {
|
|
224
|
-
this.logger.info(err.message);
|
|
225
|
-
await this.sleep(this.retryDelay);
|
|
226
|
-
}
|
|
227
|
-
else {
|
|
228
|
-
this.logger.error(`${pid} was not able to acquire lock. Ran into error: ${err.message}`);
|
|
229
|
-
throw PersistenceError.createCrossPlatformLockError(err.message);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
else {
|
|
233
|
-
throw err;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
this.logger.error(`${pid} was not able to acquire lock. Exceeded amount of retries set in the options`);
|
|
238
|
-
throw PersistenceError.createCrossPlatformLockError("Not able to acquire lock. Exceeded amount of retries set in options");
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* unlocks cache file by deleting .lockfile.
|
|
242
|
-
*/
|
|
243
|
-
async unlock() {
|
|
244
|
-
try {
|
|
245
|
-
if (this.lockFileHandle) {
|
|
246
|
-
// if we have a file handle to the .lockfile, delete lock file
|
|
247
|
-
await promises.unlink(this.lockFilePath);
|
|
248
|
-
await this.lockFileHandle.close();
|
|
249
|
-
this.logger.info("lockfile deleted");
|
|
250
|
-
}
|
|
251
|
-
else {
|
|
252
|
-
this.logger.warning("lockfile handle does not exist, so lockfile could not be deleted");
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
catch (err) {
|
|
256
|
-
if (isNodeError(err)) {
|
|
257
|
-
if (err.code === Constants$1.ENOENT_ERROR) {
|
|
258
|
-
this.logger.info("Tried to unlock but lockfile does not exist");
|
|
259
|
-
}
|
|
260
|
-
else {
|
|
261
|
-
this.logger.error(`${pid} was not able to release lock. Ran into error: ${err.message}`);
|
|
262
|
-
throw PersistenceError.createCrossPlatformLockError(err.message);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
else {
|
|
266
|
-
throw err;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
sleep(ms) {
|
|
271
|
-
return new Promise((resolve) => {
|
|
272
|
-
setTimeout(resolve, ms);
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/*! @azure/msal-node-extensions v1.5.13 2025-05-06 */
|
|
278
|
-
|
|
279
|
-
/*
|
|
280
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
281
|
-
* Licensed under the MIT License.
|
|
282
|
-
*/
|
|
283
|
-
/**
|
|
284
|
-
* MSAL cache plugin which enables callers to write the MSAL cache to disk on Windows,
|
|
285
|
-
* macOs, and Linux.
|
|
286
|
-
*
|
|
287
|
-
* - Persistence can be one of:
|
|
288
|
-
* - FilePersistence: Writes and reads from an unencrypted file. Can be used on Windows,
|
|
289
|
-
* macOs, or Linux.
|
|
290
|
-
* - FilePersistenceWithDataProtection: Used on Windows, writes and reads from file encrypted
|
|
291
|
-
* with windows dpapi-addon.
|
|
292
|
-
* - KeychainPersistence: Used on macOs, writes and reads from keychain.
|
|
293
|
-
* - LibSecretPersistence: Used on linux, writes and reads from secret service API. Requires
|
|
294
|
-
* libsecret be installed.
|
|
295
|
-
*/
|
|
296
|
-
class PersistenceCachePlugin {
|
|
297
|
-
constructor(persistence, lockOptions) {
|
|
298
|
-
this.persistence = persistence;
|
|
299
|
-
// initialize logger
|
|
300
|
-
this.logger = persistence.getLogger();
|
|
301
|
-
// create file lock
|
|
302
|
-
this.lockFilePath = `${this.persistence.getFilePath()}.lockfile`;
|
|
303
|
-
this.crossPlatformLock = new CrossPlatformLock(this.lockFilePath, this.logger, lockOptions);
|
|
304
|
-
// initialize default values
|
|
305
|
-
this.lastSync = 0;
|
|
306
|
-
this.currentCache = null;
|
|
307
|
-
}
|
|
308
|
-
/**
|
|
309
|
-
* Reads from storage and saves an in-memory copy. If persistence has not been updated
|
|
310
|
-
* since last time data was read, in memory copy is used.
|
|
311
|
-
*
|
|
312
|
-
* If cacheContext.cacheHasChanged === true, then file lock is created and not deleted until
|
|
313
|
-
* afterCacheAccess() is called, to prevent the cache file from changing in between
|
|
314
|
-
* beforeCacheAccess() and afterCacheAccess().
|
|
315
|
-
*/
|
|
316
|
-
async beforeCacheAccess(cacheContext) {
|
|
317
|
-
this.logger.info("Executing before cache access");
|
|
318
|
-
const reloadNecessary = await this.persistence.reloadNecessary(this.lastSync);
|
|
319
|
-
if (!reloadNecessary && this.currentCache !== null) {
|
|
320
|
-
if (cacheContext.cacheHasChanged) {
|
|
321
|
-
this.logger.verbose("Cache context has changed");
|
|
322
|
-
await this.crossPlatformLock.lock();
|
|
323
|
-
}
|
|
324
|
-
return;
|
|
325
|
-
}
|
|
326
|
-
try {
|
|
327
|
-
this.logger.info(`Reload necessary. Last sync time: ${this.lastSync}`);
|
|
328
|
-
await this.crossPlatformLock.lock();
|
|
329
|
-
this.currentCache = await this.persistence.load();
|
|
330
|
-
this.lastSync = new Date().getTime();
|
|
331
|
-
if (this.currentCache) {
|
|
332
|
-
cacheContext.tokenCache.deserialize(this.currentCache);
|
|
333
|
-
}
|
|
334
|
-
else {
|
|
335
|
-
this.logger.info("Cache empty.");
|
|
336
|
-
}
|
|
337
|
-
this.logger.info(`Last sync time updated to: ${this.lastSync}`);
|
|
338
|
-
}
|
|
339
|
-
finally {
|
|
340
|
-
if (!cacheContext.cacheHasChanged) {
|
|
341
|
-
await this.crossPlatformLock.unlock();
|
|
342
|
-
this.logger.info(`Pid ${pid} released lock`);
|
|
343
|
-
}
|
|
344
|
-
else {
|
|
345
|
-
this.logger.info(`Pid ${pid} beforeCacheAccess did not release lock`);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
/**
|
|
350
|
-
* Writes to storage if MSAL in memory copy of cache has been changed.
|
|
351
|
-
*/
|
|
352
|
-
async afterCacheAccess(cacheContext) {
|
|
353
|
-
this.logger.info("Executing after cache access");
|
|
354
|
-
try {
|
|
355
|
-
if (cacheContext.cacheHasChanged) {
|
|
356
|
-
this.logger.info("Msal in-memory cache has changed. Writing changes to persistence");
|
|
357
|
-
this.currentCache = cacheContext.tokenCache.serialize();
|
|
358
|
-
await this.persistence.save(this.currentCache);
|
|
359
|
-
}
|
|
360
|
-
else {
|
|
361
|
-
this.logger.info("Msal in-memory cache has not changed. Did not write to persistence");
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
finally {
|
|
365
|
-
await this.crossPlatformLock.unlock();
|
|
366
|
-
this.logger.info(`Pid ${pid} afterCacheAccess released lock`);
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
/*! @azure/msal-node-extensions v1.5.13 2025-05-06 */
|
|
372
|
-
|
|
373
|
-
/*
|
|
374
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
375
|
-
* Licensed under the MIT License.
|
|
376
|
-
*/
|
|
377
|
-
class BasePersistence {
|
|
378
|
-
async verifyPersistence() {
|
|
379
|
-
// We are using a different location for the test to avoid overriding the functional cache
|
|
380
|
-
const persistenceValidator = await this.createForPersistenceValidation();
|
|
381
|
-
try {
|
|
382
|
-
await persistenceValidator.save(Constants$1.PERSISTENCE_TEST_DATA);
|
|
383
|
-
const retrievedDummyData = await persistenceValidator.load();
|
|
384
|
-
if (!retrievedDummyData) {
|
|
385
|
-
throw PersistenceError.createCachePersistenceError("Persistence check failed. Data was written but it could not be read. " +
|
|
386
|
-
"Possible cause: on Linux, LibSecret is installed but D-Bus isn't running \
|
|
387
|
-
because it cannot be started over SSH.");
|
|
388
|
-
}
|
|
389
|
-
if (retrievedDummyData !== Constants$1.PERSISTENCE_TEST_DATA) {
|
|
390
|
-
throw PersistenceError.createCachePersistenceError(`Persistence check failed. Data written ${Constants$1.PERSISTENCE_TEST_DATA} is different \
|
|
391
|
-
from data read ${retrievedDummyData}`);
|
|
392
|
-
}
|
|
393
|
-
await persistenceValidator.delete();
|
|
394
|
-
return true;
|
|
395
|
-
}
|
|
396
|
-
catch (e) {
|
|
397
|
-
throw PersistenceError.createCachePersistenceError(`Verifing persistence failed with the error: ${e}`);
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
/*! @azure/msal-node-extensions v1.5.13 2025-05-06 */
|
|
403
|
-
/*! @azure/msal-common v15.6.0 2025-05-06 */
|
|
404
|
-
/*
|
|
405
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
406
|
-
* Licensed under the MIT License.
|
|
407
|
-
*/
|
|
408
|
-
const Constants = {
|
|
409
|
-
EMPTY_STRING: ""};
|
|
410
|
-
|
|
411
|
-
/*! @azure/msal-node-extensions v1.5.13 2025-05-06 */
|
|
412
|
-
|
|
413
|
-
/*! @azure/msal-common v15.6.0 2025-05-06 */
|
|
414
|
-
|
|
415
|
-
/*
|
|
416
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
417
|
-
* Licensed under the MIT License.
|
|
418
|
-
*/
|
|
419
|
-
/**
|
|
420
|
-
* Log message level.
|
|
421
|
-
*/
|
|
422
|
-
var LogLevel$1;
|
|
423
|
-
(function (LogLevel) {
|
|
424
|
-
LogLevel[LogLevel["Error"] = 0] = "Error";
|
|
425
|
-
LogLevel[LogLevel["Warning"] = 1] = "Warning";
|
|
426
|
-
LogLevel[LogLevel["Info"] = 2] = "Info";
|
|
427
|
-
LogLevel[LogLevel["Verbose"] = 3] = "Verbose";
|
|
428
|
-
LogLevel[LogLevel["Trace"] = 4] = "Trace";
|
|
429
|
-
})(LogLevel$1 || (LogLevel$1 = {}));
|
|
430
|
-
/**
|
|
431
|
-
* Class which facilitates logging of messages to a specific place.
|
|
432
|
-
*/
|
|
433
|
-
class Logger {
|
|
434
|
-
constructor(loggerOptions, packageName, packageVersion) {
|
|
435
|
-
// Current log level, defaults to info.
|
|
436
|
-
this.level = LogLevel$1.Info;
|
|
437
|
-
const setLoggerOptions = loggerOptions || Logger.createDefaultLoggerOptions();
|
|
438
|
-
this.localCallback =
|
|
439
|
-
setLoggerOptions.loggerCallback;
|
|
440
|
-
this.piiLoggingEnabled = setLoggerOptions.piiLoggingEnabled || false;
|
|
441
|
-
this.level =
|
|
442
|
-
typeof setLoggerOptions.logLevel === "number"
|
|
443
|
-
? setLoggerOptions.logLevel
|
|
444
|
-
: LogLevel$1.Info;
|
|
445
|
-
this.correlationId =
|
|
446
|
-
setLoggerOptions.correlationId || Constants.EMPTY_STRING;
|
|
447
|
-
this.packageName = packageName || Constants.EMPTY_STRING;
|
|
448
|
-
this.packageVersion = packageVersion || Constants.EMPTY_STRING;
|
|
449
|
-
}
|
|
450
|
-
static createDefaultLoggerOptions() {
|
|
451
|
-
return {
|
|
452
|
-
loggerCallback: () => {
|
|
453
|
-
// allow users to not set loggerCallback
|
|
454
|
-
},
|
|
455
|
-
piiLoggingEnabled: false,
|
|
456
|
-
logLevel: LogLevel$1.Info,
|
|
457
|
-
};
|
|
458
|
-
}
|
|
459
|
-
/**
|
|
460
|
-
* Create new Logger with existing configurations.
|
|
461
|
-
*/
|
|
462
|
-
clone(packageName, packageVersion, correlationId) {
|
|
463
|
-
return new Logger({
|
|
464
|
-
loggerCallback: this.localCallback,
|
|
465
|
-
piiLoggingEnabled: this.piiLoggingEnabled,
|
|
466
|
-
logLevel: this.level,
|
|
467
|
-
correlationId: correlationId || this.correlationId,
|
|
468
|
-
}, packageName, packageVersion);
|
|
469
|
-
}
|
|
470
|
-
/**
|
|
471
|
-
* Log message with required options.
|
|
472
|
-
*/
|
|
473
|
-
logMessage(logMessage, options) {
|
|
474
|
-
if (options.logLevel > this.level ||
|
|
475
|
-
(!this.piiLoggingEnabled && options.containsPii)) {
|
|
476
|
-
return;
|
|
477
|
-
}
|
|
478
|
-
const timestamp = new Date().toUTCString();
|
|
479
|
-
// Add correlationId to logs if set, correlationId provided on log messages take precedence
|
|
480
|
-
const logHeader = `[${timestamp}] : [${options.correlationId || this.correlationId || ""}]`;
|
|
481
|
-
const log = `${logHeader} : ${this.packageName}@${this.packageVersion} : ${LogLevel$1[options.logLevel]} - ${logMessage}`;
|
|
482
|
-
// debug(`msal:${LogLevel[options.logLevel]}${options.containsPii ? "-Pii": Constants.EMPTY_STRING}${options.context ? `:${options.context}` : Constants.EMPTY_STRING}`)(logMessage);
|
|
483
|
-
this.executeCallback(options.logLevel, log, options.containsPii || false);
|
|
484
|
-
}
|
|
485
|
-
/**
|
|
486
|
-
* Execute callback with message.
|
|
487
|
-
*/
|
|
488
|
-
executeCallback(level, message, containsPii) {
|
|
489
|
-
if (this.localCallback) {
|
|
490
|
-
this.localCallback(level, message, containsPii);
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
/**
|
|
494
|
-
* Logs error messages.
|
|
495
|
-
*/
|
|
496
|
-
error(message, correlationId) {
|
|
497
|
-
this.logMessage(message, {
|
|
498
|
-
logLevel: LogLevel$1.Error,
|
|
499
|
-
containsPii: false,
|
|
500
|
-
correlationId: correlationId || Constants.EMPTY_STRING,
|
|
501
|
-
});
|
|
502
|
-
}
|
|
503
|
-
/**
|
|
504
|
-
* Logs error messages with PII.
|
|
505
|
-
*/
|
|
506
|
-
errorPii(message, correlationId) {
|
|
507
|
-
this.logMessage(message, {
|
|
508
|
-
logLevel: LogLevel$1.Error,
|
|
509
|
-
containsPii: true,
|
|
510
|
-
correlationId: correlationId || Constants.EMPTY_STRING,
|
|
511
|
-
});
|
|
512
|
-
}
|
|
513
|
-
/**
|
|
514
|
-
* Logs warning messages.
|
|
515
|
-
*/
|
|
516
|
-
warning(message, correlationId) {
|
|
517
|
-
this.logMessage(message, {
|
|
518
|
-
logLevel: LogLevel$1.Warning,
|
|
519
|
-
containsPii: false,
|
|
520
|
-
correlationId: correlationId || Constants.EMPTY_STRING,
|
|
521
|
-
});
|
|
522
|
-
}
|
|
523
|
-
/**
|
|
524
|
-
* Logs warning messages with PII.
|
|
525
|
-
*/
|
|
526
|
-
warningPii(message, correlationId) {
|
|
527
|
-
this.logMessage(message, {
|
|
528
|
-
logLevel: LogLevel$1.Warning,
|
|
529
|
-
containsPii: true,
|
|
530
|
-
correlationId: correlationId || Constants.EMPTY_STRING,
|
|
531
|
-
});
|
|
532
|
-
}
|
|
533
|
-
/**
|
|
534
|
-
* Logs info messages.
|
|
535
|
-
*/
|
|
536
|
-
info(message, correlationId) {
|
|
537
|
-
this.logMessage(message, {
|
|
538
|
-
logLevel: LogLevel$1.Info,
|
|
539
|
-
containsPii: false,
|
|
540
|
-
correlationId: correlationId || Constants.EMPTY_STRING,
|
|
541
|
-
});
|
|
542
|
-
}
|
|
543
|
-
/**
|
|
544
|
-
* Logs info messages with PII.
|
|
545
|
-
*/
|
|
546
|
-
infoPii(message, correlationId) {
|
|
547
|
-
this.logMessage(message, {
|
|
548
|
-
logLevel: LogLevel$1.Info,
|
|
549
|
-
containsPii: true,
|
|
550
|
-
correlationId: correlationId || Constants.EMPTY_STRING,
|
|
551
|
-
});
|
|
552
|
-
}
|
|
553
|
-
/**
|
|
554
|
-
* Logs verbose messages.
|
|
555
|
-
*/
|
|
556
|
-
verbose(message, correlationId) {
|
|
557
|
-
this.logMessage(message, {
|
|
558
|
-
logLevel: LogLevel$1.Verbose,
|
|
559
|
-
containsPii: false,
|
|
560
|
-
correlationId: correlationId || Constants.EMPTY_STRING,
|
|
561
|
-
});
|
|
562
|
-
}
|
|
563
|
-
/**
|
|
564
|
-
* Logs verbose messages with PII.
|
|
565
|
-
*/
|
|
566
|
-
verbosePii(message, correlationId) {
|
|
567
|
-
this.logMessage(message, {
|
|
568
|
-
logLevel: LogLevel$1.Verbose,
|
|
569
|
-
containsPii: true,
|
|
570
|
-
correlationId: correlationId || Constants.EMPTY_STRING,
|
|
571
|
-
});
|
|
572
|
-
}
|
|
573
|
-
/**
|
|
574
|
-
* Logs trace messages.
|
|
575
|
-
*/
|
|
576
|
-
trace(message, correlationId) {
|
|
577
|
-
this.logMessage(message, {
|
|
578
|
-
logLevel: LogLevel$1.Trace,
|
|
579
|
-
containsPii: false,
|
|
580
|
-
correlationId: correlationId || Constants.EMPTY_STRING,
|
|
581
|
-
});
|
|
582
|
-
}
|
|
583
|
-
/**
|
|
584
|
-
* Logs trace messages with PII.
|
|
585
|
-
*/
|
|
586
|
-
tracePii(message, correlationId) {
|
|
587
|
-
this.logMessage(message, {
|
|
588
|
-
logLevel: LogLevel$1.Trace,
|
|
589
|
-
containsPii: true,
|
|
590
|
-
correlationId: correlationId || Constants.EMPTY_STRING,
|
|
591
|
-
});
|
|
592
|
-
}
|
|
593
|
-
/**
|
|
594
|
-
* Returns whether PII Logging is enabled or not.
|
|
595
|
-
*/
|
|
596
|
-
isPiiLoggingEnabled() {
|
|
597
|
-
return this.piiLoggingEnabled || false;
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
/*! @azure/msal-node-extensions v1.5.13 2025-05-06 */
|
|
602
|
-
|
|
603
|
-
/*
|
|
604
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
605
|
-
* Licensed under the MIT License.
|
|
606
|
-
*/
|
|
607
|
-
/**
|
|
608
|
-
* Reads and writes data to file specified by file location. File contents are not
|
|
609
|
-
* encrypted.
|
|
610
|
-
*
|
|
611
|
-
* If file or directory has not been created, it FilePersistence.create() will create
|
|
612
|
-
* file and any directories in the path recursively.
|
|
613
|
-
*/
|
|
614
|
-
class FilePersistence extends BasePersistence {
|
|
615
|
-
constructor(fileLocation, loggerOptions) {
|
|
616
|
-
super();
|
|
617
|
-
this.logger = new Logger(loggerOptions || FilePersistence.createDefaultLoggerOptions());
|
|
618
|
-
this.filePath = fileLocation;
|
|
619
|
-
}
|
|
620
|
-
static async create(fileLocation, loggerOptions) {
|
|
621
|
-
const filePersistence = new FilePersistence(fileLocation, loggerOptions);
|
|
622
|
-
await filePersistence.createCacheFile();
|
|
623
|
-
return filePersistence;
|
|
624
|
-
}
|
|
625
|
-
async save(contents) {
|
|
626
|
-
try {
|
|
627
|
-
await promises.writeFile(this.getFilePath(), contents, "utf-8");
|
|
628
|
-
}
|
|
629
|
-
catch (err) {
|
|
630
|
-
if (isNodeError(err)) {
|
|
631
|
-
throw PersistenceError.createFileSystemError(err.code || ErrorCodes.UNKNOWN, err.message);
|
|
632
|
-
}
|
|
633
|
-
else {
|
|
634
|
-
throw err;
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
async saveBuffer(contents) {
|
|
639
|
-
try {
|
|
640
|
-
await promises.writeFile(this.getFilePath(), contents);
|
|
641
|
-
}
|
|
642
|
-
catch (err) {
|
|
643
|
-
if (isNodeError(err)) {
|
|
644
|
-
throw PersistenceError.createFileSystemError(err.code || ErrorCodes.UNKNOWN, err.message);
|
|
645
|
-
}
|
|
646
|
-
else {
|
|
647
|
-
throw err;
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
async load() {
|
|
652
|
-
try {
|
|
653
|
-
return await promises.readFile(this.getFilePath(), "utf-8");
|
|
654
|
-
}
|
|
655
|
-
catch (err) {
|
|
656
|
-
if (isNodeError(err)) {
|
|
657
|
-
throw PersistenceError.createFileSystemError(err.code || ErrorCodes.UNKNOWN, err.message);
|
|
658
|
-
}
|
|
659
|
-
else {
|
|
660
|
-
throw err;
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
async loadBuffer() {
|
|
665
|
-
try {
|
|
666
|
-
return await promises.readFile(this.getFilePath());
|
|
667
|
-
}
|
|
668
|
-
catch (err) {
|
|
669
|
-
if (isNodeError(err)) {
|
|
670
|
-
throw PersistenceError.createFileSystemError(err.code || ErrorCodes.UNKNOWN, err.message);
|
|
671
|
-
}
|
|
672
|
-
else {
|
|
673
|
-
throw err;
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
async delete() {
|
|
678
|
-
try {
|
|
679
|
-
await promises.unlink(this.getFilePath());
|
|
680
|
-
return true;
|
|
681
|
-
}
|
|
682
|
-
catch (err) {
|
|
683
|
-
if (isNodeError(err)) {
|
|
684
|
-
if (err.code === Constants$1.ENOENT_ERROR) {
|
|
685
|
-
// file does not exist, so it was not deleted
|
|
686
|
-
this.logger.warning("Cache file does not exist, so it could not be deleted");
|
|
687
|
-
return false;
|
|
688
|
-
}
|
|
689
|
-
throw PersistenceError.createFileSystemError(err.code || ErrorCodes.UNKNOWN, err.message);
|
|
690
|
-
}
|
|
691
|
-
else {
|
|
692
|
-
throw err;
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
getFilePath() {
|
|
697
|
-
return this.filePath;
|
|
698
|
-
}
|
|
699
|
-
async reloadNecessary(lastSync) {
|
|
700
|
-
return lastSync < (await this.timeLastModified());
|
|
701
|
-
}
|
|
702
|
-
getLogger() {
|
|
703
|
-
return this.logger;
|
|
704
|
-
}
|
|
705
|
-
createForPersistenceValidation() {
|
|
706
|
-
const testCacheFileLocation = `${dirname(this.filePath)}/test.cache`;
|
|
707
|
-
return FilePersistence.create(testCacheFileLocation);
|
|
708
|
-
}
|
|
709
|
-
static createDefaultLoggerOptions() {
|
|
710
|
-
return {
|
|
711
|
-
loggerCallback: () => {
|
|
712
|
-
// allow users to not set loggerCallback
|
|
713
|
-
},
|
|
714
|
-
piiLoggingEnabled: false,
|
|
715
|
-
logLevel: LogLevel$1.Info,
|
|
716
|
-
};
|
|
717
|
-
}
|
|
718
|
-
async timeLastModified() {
|
|
719
|
-
try {
|
|
720
|
-
const stats = await promises.stat(this.filePath);
|
|
721
|
-
return stats.mtime.getTime();
|
|
722
|
-
}
|
|
723
|
-
catch (err) {
|
|
724
|
-
if (isNodeError(err)) {
|
|
725
|
-
if (err.code === Constants$1.ENOENT_ERROR) {
|
|
726
|
-
// file does not exist, so it's never been modified
|
|
727
|
-
this.logger.verbose("Cache file does not exist");
|
|
728
|
-
return 0;
|
|
729
|
-
}
|
|
730
|
-
throw PersistenceError.createFileSystemError(err.code || ErrorCodes.UNKNOWN, err.message);
|
|
731
|
-
}
|
|
732
|
-
else {
|
|
733
|
-
throw err;
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
}
|
|
737
|
-
async createCacheFile() {
|
|
738
|
-
await this.createFileDirectory();
|
|
739
|
-
// File is created only if it does not exist
|
|
740
|
-
const fileHandle = await promises.open(this.filePath, "a");
|
|
741
|
-
await fileHandle.close();
|
|
742
|
-
this.logger.info(`File created at ${this.filePath}`);
|
|
743
|
-
}
|
|
744
|
-
async createFileDirectory() {
|
|
745
|
-
try {
|
|
746
|
-
await promises.mkdir(dirname(this.filePath), { recursive: true });
|
|
747
|
-
}
|
|
748
|
-
catch (err) {
|
|
749
|
-
if (isNodeError(err)) {
|
|
750
|
-
if (err.code === Constants$1.EEXIST_ERROR) {
|
|
751
|
-
this.logger.info(`Directory ${dirname(this.filePath)} already exists`);
|
|
752
|
-
}
|
|
753
|
-
else {
|
|
754
|
-
throw PersistenceError.createFileSystemError(err.code || ErrorCodes.UNKNOWN, err.message);
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
else {
|
|
758
|
-
throw err;
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
/*! @azure/msal-node-extensions v1.5.13 2025-05-06 */
|
|
765
|
-
|
|
766
|
-
/*
|
|
767
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
768
|
-
* Licensed under the MIT License.
|
|
769
|
-
*/
|
|
770
|
-
class UnavailableDpapi {
|
|
771
|
-
constructor(errorMessage) {
|
|
772
|
-
this.errorMessage = errorMessage;
|
|
773
|
-
}
|
|
774
|
-
protectData() {
|
|
775
|
-
throw new Error(this.errorMessage);
|
|
776
|
-
}
|
|
777
|
-
unprotectData() {
|
|
778
|
-
throw new Error(this.errorMessage);
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
let Dpapi;
|
|
782
|
-
if (process.platform !== "win32") {
|
|
783
|
-
Dpapi = new UnavailableDpapi("Dpapi is not supported on this platform");
|
|
784
|
-
}
|
|
785
|
-
else {
|
|
786
|
-
// In .mjs files, require is not defined. We need to use createRequire to get a require function
|
|
787
|
-
const safeRequire = typeof require !== "undefined"
|
|
788
|
-
? require
|
|
789
|
-
: createRequire(import.meta.url);
|
|
790
|
-
try {
|
|
791
|
-
Dpapi = safeRequire(`../bin/${process.arch}/dpapi`);
|
|
792
|
-
}
|
|
793
|
-
catch (e) {
|
|
794
|
-
Dpapi = new UnavailableDpapi("Dpapi bindings unavailable");
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
/*! @azure/msal-node-extensions v1.5.13 2025-05-06 */
|
|
799
|
-
/*
|
|
800
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
801
|
-
* Licensed under the MIT License.
|
|
802
|
-
*/
|
|
803
|
-
/**
|
|
804
|
-
* Specifies the scope of the data protection - either the current user or the local
|
|
805
|
-
* machine.
|
|
806
|
-
*
|
|
807
|
-
* You do not need a key to protect or unprotect the data.
|
|
808
|
-
* If you set the Scope to CurrentUser, only applications running on your credentials can
|
|
809
|
-
* unprotect the data; however, that means that any application running on your credentials
|
|
810
|
-
* can access the protected data. If you set the Scope to LocalMachine, any full-trust
|
|
811
|
-
* application on the computer can unprotect, access, and modify the data.
|
|
812
|
-
*
|
|
813
|
-
*/
|
|
814
|
-
const DataProtectionScope = {
|
|
815
|
-
CurrentUser: "CurrentUser"};
|
|
816
|
-
|
|
817
|
-
/*! @azure/msal-node-extensions v1.5.13 2025-05-06 */
|
|
818
|
-
|
|
819
|
-
/*
|
|
820
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
821
|
-
* Licensed under the MIT License.
|
|
822
|
-
*/
|
|
823
|
-
/**
|
|
824
|
-
* Uses CryptProtectData and CryptUnprotectData on Windows to encrypt and decrypt file contents.
|
|
825
|
-
*
|
|
826
|
-
* scope: Scope of the data protection. Either local user or the current machine
|
|
827
|
-
* optionalEntropy: Password or other additional entropy used to encrypt the data
|
|
828
|
-
*/
|
|
829
|
-
class FilePersistenceWithDataProtection extends BasePersistence {
|
|
830
|
-
constructor(filePersistence, scope, optionalEntropy) {
|
|
831
|
-
super();
|
|
832
|
-
this.scope = scope;
|
|
833
|
-
this.optionalEntropy = optionalEntropy
|
|
834
|
-
? Buffer.from(optionalEntropy, "utf-8")
|
|
835
|
-
: null;
|
|
836
|
-
this.filePersistence = filePersistence;
|
|
837
|
-
}
|
|
838
|
-
static async create(fileLocation, scope, optionalEntropy, loggerOptions) {
|
|
839
|
-
const filePersistence = await FilePersistence.create(fileLocation, loggerOptions);
|
|
840
|
-
const persistence = new FilePersistenceWithDataProtection(filePersistence, scope, optionalEntropy);
|
|
841
|
-
return persistence;
|
|
842
|
-
}
|
|
843
|
-
async save(contents) {
|
|
844
|
-
try {
|
|
845
|
-
const encryptedContents = Dpapi.protectData(Buffer.from(contents, "utf-8"), this.optionalEntropy, this.scope.toString());
|
|
846
|
-
await this.filePersistence.saveBuffer(encryptedContents);
|
|
847
|
-
}
|
|
848
|
-
catch (err) {
|
|
849
|
-
if (isNodeError(err)) {
|
|
850
|
-
throw PersistenceError.createFilePersistenceWithDPAPIError(err.message);
|
|
851
|
-
}
|
|
852
|
-
else {
|
|
853
|
-
throw err;
|
|
854
|
-
}
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
async load() {
|
|
858
|
-
try {
|
|
859
|
-
const encryptedContents = await this.filePersistence.loadBuffer();
|
|
860
|
-
if (typeof encryptedContents === "undefined" ||
|
|
861
|
-
!encryptedContents ||
|
|
862
|
-
0 === encryptedContents.length) {
|
|
863
|
-
this.filePersistence
|
|
864
|
-
.getLogger()
|
|
865
|
-
.info("Encrypted contents loaded from file were null or empty");
|
|
866
|
-
return null;
|
|
867
|
-
}
|
|
868
|
-
return Dpapi.unprotectData(encryptedContents, this.optionalEntropy, this.scope.toString()).toString();
|
|
869
|
-
}
|
|
870
|
-
catch (err) {
|
|
871
|
-
if (isNodeError(err)) {
|
|
872
|
-
throw PersistenceError.createFilePersistenceWithDPAPIError(err.message);
|
|
873
|
-
}
|
|
874
|
-
else {
|
|
875
|
-
throw err;
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
}
|
|
879
|
-
async delete() {
|
|
880
|
-
return this.filePersistence.delete();
|
|
881
|
-
}
|
|
882
|
-
async reloadNecessary(lastSync) {
|
|
883
|
-
return this.filePersistence.reloadNecessary(lastSync);
|
|
884
|
-
}
|
|
885
|
-
getFilePath() {
|
|
886
|
-
return this.filePersistence.getFilePath();
|
|
887
|
-
}
|
|
888
|
-
getLogger() {
|
|
889
|
-
return this.filePersistence.getLogger();
|
|
890
|
-
}
|
|
891
|
-
createForPersistenceValidation() {
|
|
892
|
-
const testCacheFileLocation = `${dirname(this.filePersistence.getFilePath())}/test.cache`;
|
|
893
|
-
return FilePersistenceWithDataProtection.create(testCacheFileLocation, DataProtectionScope.CurrentUser);
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
/*! @azure/msal-node-extensions v1.5.13 2025-05-06 */
|
|
898
|
-
|
|
899
|
-
/*
|
|
900
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
901
|
-
* Licensed under the MIT License.
|
|
902
|
-
*/
|
|
903
|
-
/**
|
|
904
|
-
* Uses reads and writes passwords to macOS keychain
|
|
905
|
-
*
|
|
906
|
-
* serviceName: Identifier used as key for whatever value is stored
|
|
907
|
-
* accountName: Account under which password should be stored
|
|
908
|
-
*/
|
|
909
|
-
class KeychainPersistence extends BasePersistence {
|
|
910
|
-
constructor(filePersistence, serviceName, accountName) {
|
|
911
|
-
super();
|
|
912
|
-
this.filePersistence = filePersistence;
|
|
913
|
-
this.serviceName = serviceName;
|
|
914
|
-
this.accountName = accountName;
|
|
915
|
-
}
|
|
916
|
-
static async create(fileLocation, serviceName, accountName, loggerOptions) {
|
|
917
|
-
const filePersistence = await FilePersistence.create(fileLocation, loggerOptions);
|
|
918
|
-
const persistence = new KeychainPersistence(filePersistence, serviceName, accountName);
|
|
919
|
-
return persistence;
|
|
920
|
-
}
|
|
921
|
-
async save(contents) {
|
|
922
|
-
try {
|
|
923
|
-
await keytar.setPassword(this.serviceName, this.accountName, contents);
|
|
924
|
-
}
|
|
925
|
-
catch (err) {
|
|
926
|
-
if (isNodeError(err)) {
|
|
927
|
-
throw PersistenceError.createKeychainPersistenceError(err.message);
|
|
928
|
-
}
|
|
929
|
-
else {
|
|
930
|
-
throw err;
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
// Write dummy data to update file mtime
|
|
934
|
-
await this.filePersistence.save("{}");
|
|
935
|
-
}
|
|
936
|
-
async load() {
|
|
937
|
-
try {
|
|
938
|
-
return await keytar.getPassword(this.serviceName, this.accountName);
|
|
939
|
-
}
|
|
940
|
-
catch (err) {
|
|
941
|
-
if (isNodeError(err)) {
|
|
942
|
-
throw PersistenceError.createKeychainPersistenceError(err.message);
|
|
943
|
-
}
|
|
944
|
-
else {
|
|
945
|
-
throw err;
|
|
946
|
-
}
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
|
-
async delete() {
|
|
950
|
-
try {
|
|
951
|
-
await this.filePersistence.delete();
|
|
952
|
-
return await keytar.deletePassword(this.serviceName, this.accountName);
|
|
953
|
-
}
|
|
954
|
-
catch (err) {
|
|
955
|
-
if (isNodeError(err)) {
|
|
956
|
-
throw PersistenceError.createKeychainPersistenceError(err.message);
|
|
957
|
-
}
|
|
958
|
-
else {
|
|
959
|
-
throw err;
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
async reloadNecessary(lastSync) {
|
|
964
|
-
return this.filePersistence.reloadNecessary(lastSync);
|
|
965
|
-
}
|
|
966
|
-
getFilePath() {
|
|
967
|
-
return this.filePersistence.getFilePath();
|
|
968
|
-
}
|
|
969
|
-
getLogger() {
|
|
970
|
-
return this.filePersistence.getLogger();
|
|
971
|
-
}
|
|
972
|
-
createForPersistenceValidation() {
|
|
973
|
-
const testCacheFileLocation = `${dirname(this.filePersistence.getFilePath())}/test.cache`;
|
|
974
|
-
return KeychainPersistence.create(testCacheFileLocation, "persistenceValidationServiceName", "persistencValidationAccountName");
|
|
975
|
-
}
|
|
976
|
-
}
|
|
977
|
-
|
|
978
|
-
/*! @azure/msal-node-extensions v1.5.13 2025-05-06 */
|
|
979
|
-
|
|
980
|
-
/*
|
|
981
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
982
|
-
* Licensed under the MIT License.
|
|
983
|
-
*/
|
|
984
|
-
/**
|
|
985
|
-
* Uses reads and writes passwords to Secret Service API/libsecret. Requires libsecret
|
|
986
|
-
* to be installed.
|
|
987
|
-
*
|
|
988
|
-
* serviceName: Identifier used as key for whatever value is stored
|
|
989
|
-
* accountName: Account under which password should be stored
|
|
990
|
-
*/
|
|
991
|
-
class LibSecretPersistence extends BasePersistence {
|
|
992
|
-
constructor(filePersistence, serviceName, accountName) {
|
|
993
|
-
super();
|
|
994
|
-
this.filePersistence = filePersistence;
|
|
995
|
-
this.serviceName = serviceName;
|
|
996
|
-
this.accountName = accountName;
|
|
997
|
-
}
|
|
998
|
-
static async create(fileLocation, serviceName, accountName, loggerOptions) {
|
|
999
|
-
const filePersistence = await FilePersistence.create(fileLocation, loggerOptions);
|
|
1000
|
-
const persistence = new LibSecretPersistence(filePersistence, serviceName, accountName);
|
|
1001
|
-
return persistence;
|
|
1002
|
-
}
|
|
1003
|
-
async save(contents) {
|
|
1004
|
-
try {
|
|
1005
|
-
await keytar.setPassword(this.serviceName, this.accountName, contents);
|
|
1006
|
-
}
|
|
1007
|
-
catch (err) {
|
|
1008
|
-
if (isNodeError(err)) {
|
|
1009
|
-
throw PersistenceError.createLibSecretError(err.message);
|
|
1010
|
-
}
|
|
1011
|
-
else {
|
|
1012
|
-
throw err;
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
// Write dummy data to update file mtime
|
|
1016
|
-
await this.filePersistence.save("{}");
|
|
1017
|
-
}
|
|
1018
|
-
async load() {
|
|
1019
|
-
try {
|
|
1020
|
-
return await keytar.getPassword(this.serviceName, this.accountName);
|
|
1021
|
-
}
|
|
1022
|
-
catch (err) {
|
|
1023
|
-
if (isNodeError(err)) {
|
|
1024
|
-
throw PersistenceError.createLibSecretError(err.message);
|
|
1025
|
-
}
|
|
1026
|
-
else {
|
|
1027
|
-
throw err;
|
|
1028
|
-
}
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
async delete() {
|
|
1032
|
-
try {
|
|
1033
|
-
await this.filePersistence.delete();
|
|
1034
|
-
return await keytar.deletePassword(this.serviceName, this.accountName);
|
|
1035
|
-
}
|
|
1036
|
-
catch (err) {
|
|
1037
|
-
if (isNodeError(err)) {
|
|
1038
|
-
throw PersistenceError.createLibSecretError(err.message);
|
|
1039
|
-
}
|
|
1040
|
-
else {
|
|
1041
|
-
throw err;
|
|
1042
|
-
}
|
|
1043
|
-
}
|
|
1044
|
-
}
|
|
1045
|
-
async reloadNecessary(lastSync) {
|
|
1046
|
-
return this.filePersistence.reloadNecessary(lastSync);
|
|
1047
|
-
}
|
|
1048
|
-
getFilePath() {
|
|
1049
|
-
return this.filePersistence.getFilePath();
|
|
1050
|
-
}
|
|
1051
|
-
getLogger() {
|
|
1052
|
-
return this.filePersistence.getLogger();
|
|
1053
|
-
}
|
|
1054
|
-
createForPersistenceValidation() {
|
|
1055
|
-
const testCacheFileLocation = `${dirname(this.filePersistence.getFilePath())}/test.cache`;
|
|
1056
|
-
return LibSecretPersistence.create(testCacheFileLocation, "persistenceValidationServiceName", "persistencValidationAccountName");
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1059
|
-
|
|
1060
|
-
/*! @azure/msal-node-extensions v1.5.13 2025-05-06 */
|
|
1061
|
-
|
|
1062
|
-
/*
|
|
1063
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1064
|
-
* Licensed under the MIT License.
|
|
1065
|
-
*/
|
|
1066
|
-
class Environment {
|
|
1067
|
-
static get homeEnvVar() {
|
|
1068
|
-
return this.getEnvironmentVariable(Constants$1.ENVIRONMENT.HOME);
|
|
1069
|
-
}
|
|
1070
|
-
static get lognameEnvVar() {
|
|
1071
|
-
return this.getEnvironmentVariable(Constants$1.ENVIRONMENT.LOGNAME);
|
|
1072
|
-
}
|
|
1073
|
-
static get userEnvVar() {
|
|
1074
|
-
return this.getEnvironmentVariable(Constants$1.ENVIRONMENT.USER);
|
|
1075
|
-
}
|
|
1076
|
-
static get lnameEnvVar() {
|
|
1077
|
-
return this.getEnvironmentVariable(Constants$1.ENVIRONMENT.LNAME);
|
|
1078
|
-
}
|
|
1079
|
-
static get usernameEnvVar() {
|
|
1080
|
-
return this.getEnvironmentVariable(Constants$1.ENVIRONMENT.USERNAME);
|
|
1081
|
-
}
|
|
1082
|
-
static getEnvironmentVariable(name) {
|
|
1083
|
-
return process.env[name] || "";
|
|
1084
|
-
}
|
|
1085
|
-
static getEnvironmentPlatform() {
|
|
1086
|
-
return process.platform;
|
|
1087
|
-
}
|
|
1088
|
-
static isWindowsPlatform() {
|
|
1089
|
-
return this.getEnvironmentPlatform() === Platform.WINDOWS;
|
|
1090
|
-
}
|
|
1091
|
-
static isLinuxPlatform() {
|
|
1092
|
-
return this.getEnvironmentPlatform() === Platform.LINUX;
|
|
1093
|
-
}
|
|
1094
|
-
static isMacPlatform() {
|
|
1095
|
-
return this.getEnvironmentPlatform() === Platform.MACOS;
|
|
1096
|
-
}
|
|
1097
|
-
static isLinuxRootUser() {
|
|
1098
|
-
if (typeof process.getuid !== "function") {
|
|
1099
|
-
return false;
|
|
1100
|
-
}
|
|
1101
|
-
return process.getuid() === Constants$1.LINUX_ROOT_USER_GUID;
|
|
1102
|
-
}
|
|
1103
|
-
static getUserRootDirectory() {
|
|
1104
|
-
return !this.isWindowsPlatform()
|
|
1105
|
-
? this.getUserHomeDirOnUnix()
|
|
1106
|
-
: this.getUserHomeDirOnWindows();
|
|
1107
|
-
}
|
|
1108
|
-
static getUserHomeDirOnWindows() {
|
|
1109
|
-
return this.getEnvironmentVariable(Constants$1.ENVIRONMENT.LOCAL_APPLICATION_DATA);
|
|
1110
|
-
}
|
|
1111
|
-
static getUserHomeDirOnUnix() {
|
|
1112
|
-
if (this.isWindowsPlatform()) {
|
|
1113
|
-
throw PersistenceError.createNotSupportedError("Getting the user home directory for unix is not supported in windows");
|
|
1114
|
-
}
|
|
1115
|
-
if (this.homeEnvVar) {
|
|
1116
|
-
return this.homeEnvVar;
|
|
1117
|
-
}
|
|
1118
|
-
let username = null;
|
|
1119
|
-
if (this.lognameEnvVar) {
|
|
1120
|
-
username = this.lognameEnvVar;
|
|
1121
|
-
}
|
|
1122
|
-
else if (this.userEnvVar) {
|
|
1123
|
-
username = this.userEnvVar;
|
|
1124
|
-
}
|
|
1125
|
-
else if (this.lnameEnvVar) {
|
|
1126
|
-
username = this.lnameEnvVar;
|
|
1127
|
-
}
|
|
1128
|
-
else if (this.usernameEnvVar) {
|
|
1129
|
-
username = this.usernameEnvVar;
|
|
1130
|
-
}
|
|
1131
|
-
if (this.isMacPlatform()) {
|
|
1132
|
-
return username ? path.join("/Users", username) : null;
|
|
1133
|
-
}
|
|
1134
|
-
else if (this.isLinuxPlatform()) {
|
|
1135
|
-
if (this.isLinuxRootUser()) {
|
|
1136
|
-
return "/root";
|
|
1137
|
-
}
|
|
1138
|
-
else {
|
|
1139
|
-
return username ? path.join("/home", username) : null;
|
|
1140
|
-
}
|
|
1141
|
-
}
|
|
1142
|
-
else {
|
|
1143
|
-
throw PersistenceError.createNotSupportedError("Getting the user home directory for unix is not supported in windows");
|
|
1144
|
-
}
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
|
|
1148
|
-
/*! @azure/msal-node-extensions v1.5.13 2025-05-06 */
|
|
1149
|
-
|
|
1150
|
-
/*
|
|
1151
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1152
|
-
* Licensed under the MIT License.
|
|
1153
|
-
*/
|
|
1154
|
-
class PersistenceCreator {
|
|
1155
|
-
static async createPersistence(config) {
|
|
1156
|
-
let peristence;
|
|
1157
|
-
// On Windows, uses a DPAPI encrypted file
|
|
1158
|
-
if (Environment.isWindowsPlatform()) {
|
|
1159
|
-
if (!config.cachePath || !config.dataProtectionScope) {
|
|
1160
|
-
throw PersistenceError.createPersistenceNotValidatedError("Cache path and/or data protection scope not provided for the FilePersistenceWithDataProtection cache plugin");
|
|
1161
|
-
}
|
|
1162
|
-
peristence = await FilePersistenceWithDataProtection.create(config.cachePath, DataProtectionScope.CurrentUser, undefined, config.loggerOptions);
|
|
1163
|
-
}
|
|
1164
|
-
// On Mac, uses keychain.
|
|
1165
|
-
else if (Environment.isMacPlatform()) {
|
|
1166
|
-
if (!config.cachePath ||
|
|
1167
|
-
!config.serviceName ||
|
|
1168
|
-
!config.accountName) {
|
|
1169
|
-
throw PersistenceError.createPersistenceNotValidatedError("Cache path, service name and/or account name not provided for the KeychainPersistence cache plugin");
|
|
1170
|
-
}
|
|
1171
|
-
peristence = await KeychainPersistence.create(config.cachePath, config.serviceName, config.accountName, config.loggerOptions);
|
|
1172
|
-
}
|
|
1173
|
-
// On Linux, uses libsecret to store to secret service. Libsecret has to be installed.
|
|
1174
|
-
else if (Environment.isLinuxPlatform()) {
|
|
1175
|
-
if (!config.cachePath ||
|
|
1176
|
-
!config.serviceName ||
|
|
1177
|
-
!config.accountName) {
|
|
1178
|
-
throw PersistenceError.createPersistenceNotValidatedError("Cache path, service name and/or account name not provided for the LibSecretPersistence cache plugin");
|
|
1179
|
-
}
|
|
1180
|
-
peristence = await LibSecretPersistence.create(config.cachePath, config.serviceName, config.accountName, config.loggerOptions);
|
|
1181
|
-
}
|
|
1182
|
-
else {
|
|
1183
|
-
throw PersistenceError.createNotSupportedError("The current environment is not supported by msal-node-extensions yet.");
|
|
1184
|
-
}
|
|
1185
|
-
await peristence.verifyPersistence().catch(async (e) => {
|
|
1186
|
-
if (Environment.isLinuxPlatform() &&
|
|
1187
|
-
config.usePlaintextFileOnLinux) {
|
|
1188
|
-
if (!config.cachePath) {
|
|
1189
|
-
throw PersistenceError.createPersistenceNotValidatedError("Cache path not provided for the FilePersistence cache plugin");
|
|
1190
|
-
}
|
|
1191
|
-
peristence = await FilePersistence.create(config.cachePath, config.loggerOptions);
|
|
1192
|
-
const isFilePersistenceVerified = await peristence.verifyPersistence();
|
|
1193
|
-
if (isFilePersistenceVerified) {
|
|
1194
|
-
return peristence;
|
|
1195
|
-
}
|
|
1196
|
-
throw PersistenceError.createPersistenceNotVerifiedError("Persistence could not be verified");
|
|
1197
|
-
}
|
|
1198
|
-
else {
|
|
1199
|
-
throw e;
|
|
1200
|
-
}
|
|
1201
|
-
});
|
|
1202
|
-
return peristence;
|
|
1203
|
-
}
|
|
1204
|
-
}
|
|
1205
|
-
|
|
1206
|
-
/*
|
|
1207
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1208
|
-
* Licensed under the MIT License.
|
|
1209
|
-
*/
|
|
1210
|
-
var supportedPlatforms = ["win32"];
|
|
1211
|
-
var supportedArchitectures = ["x64", "ia32"];
|
|
1212
|
-
// Should be kept up to date with error status defined by MsalRuntime
|
|
1213
|
-
var ErrorStatus;
|
|
1214
|
-
(function (ErrorStatus) {
|
|
1215
|
-
ErrorStatus[ErrorStatus["Unexpected"] = 0] = "Unexpected";
|
|
1216
|
-
ErrorStatus[ErrorStatus["Reserved"] = 1] = "Reserved";
|
|
1217
|
-
ErrorStatus[ErrorStatus["InteractionRequired"] = 2] = "InteractionRequired";
|
|
1218
|
-
ErrorStatus[ErrorStatus["NoNetwork"] = 3] = "NoNetwork";
|
|
1219
|
-
ErrorStatus[ErrorStatus["NetworkTemporarilyUnavailable"] = 4] = "NetworkTemporarilyUnavailable";
|
|
1220
|
-
ErrorStatus[ErrorStatus["ServerTemporarilyUnavailable"] = 5] = "ServerTemporarilyUnavailable";
|
|
1221
|
-
ErrorStatus[ErrorStatus["ApiContractViolation"] = 6] = "ApiContractViolation";
|
|
1222
|
-
ErrorStatus[ErrorStatus["UserCanceled"] = 7] = "UserCanceled";
|
|
1223
|
-
ErrorStatus[ErrorStatus["ApplicationCanceled"] = 8] = "ApplicationCanceled";
|
|
1224
|
-
ErrorStatus[ErrorStatus["IncorrectConfiguration"] = 9] = "IncorrectConfiguration";
|
|
1225
|
-
ErrorStatus[ErrorStatus["InsufficientBuffer"] = 10] = "InsufficientBuffer";
|
|
1226
|
-
ErrorStatus[ErrorStatus["AuthorityUntrusted"] = 11] = "AuthorityUntrusted";
|
|
1227
|
-
ErrorStatus[ErrorStatus["UserSwitched"] = 12] = "UserSwitched";
|
|
1228
|
-
ErrorStatus[ErrorStatus["AccountUnusable"] = 13] = "AccountUnusable";
|
|
1229
|
-
ErrorStatus[ErrorStatus["UserDataRemovalRequired"] = 14] = "UserDataRemovalRequired";
|
|
1230
|
-
ErrorStatus[ErrorStatus["KeyNotFound"] = 15] = "KeyNotFound";
|
|
1231
|
-
ErrorStatus[ErrorStatus["AccountNotFound"] = 16] = "AccountNotFound";
|
|
1232
|
-
})(ErrorStatus || (ErrorStatus = {}));
|
|
1233
|
-
// Should be kept up to date with LogLevels defined by MsalRuntime
|
|
1234
|
-
var LogLevel;
|
|
1235
|
-
(function (LogLevel) {
|
|
1236
|
-
LogLevel[LogLevel["Trace"] = 1] = "Trace";
|
|
1237
|
-
LogLevel[LogLevel["Debug"] = 2] = "Debug";
|
|
1238
|
-
LogLevel[LogLevel["Info"] = 3] = "Info";
|
|
1239
|
-
LogLevel[LogLevel["Warning"] = 4] = "Warning";
|
|
1240
|
-
LogLevel[LogLevel["Error"] = 5] = "Error";
|
|
1241
|
-
LogLevel[LogLevel["Fatal"] = 6] = "Fatal";
|
|
1242
|
-
})(LogLevel || (LogLevel = {}));
|
|
1243
|
-
var unsupportedSystemError = {
|
|
1244
|
-
errorCode: 0,
|
|
1245
|
-
errorStatus: ErrorStatus.Unexpected,
|
|
1246
|
-
errorContext: "Platform and/or architecture are unsupported. Supported Platforms: ".concat(supportedPlatforms.join(", "), ". Supported Architectures: ").concat(supportedArchitectures.join(", "), "."),
|
|
1247
|
-
errorTag: 0
|
|
1248
|
-
};
|
|
1249
|
-
var unexpectedError = {
|
|
1250
|
-
errorCode: 0,
|
|
1251
|
-
errorStatus: ErrorStatus.Unexpected,
|
|
1252
|
-
errorContext: "Binaries could not be loaded. This is unexpected.",
|
|
1253
|
-
errorTag: 0
|
|
1254
|
-
};
|
|
1255
|
-
function getBinaryNotFoundError() {
|
|
1256
|
-
if (supportedPlatforms.includes(process.platform) && supportedArchitectures.includes(process.arch)) {
|
|
1257
|
-
return unexpectedError;
|
|
1258
|
-
}
|
|
1259
|
-
else {
|
|
1260
|
-
return unsupportedSystemError;
|
|
1261
|
-
}
|
|
1262
|
-
}
|
|
1263
|
-
var DefaultAuthParameters = /** @class */ (function () {
|
|
1264
|
-
function DefaultAuthParameters() {
|
|
1265
|
-
}
|
|
1266
|
-
DefaultAuthParameters.prototype.CreateAuthParameters = function () {
|
|
1267
|
-
throw getBinaryNotFoundError();
|
|
1268
|
-
};
|
|
1269
|
-
DefaultAuthParameters.prototype.SetRedirectUri = function () {
|
|
1270
|
-
throw getBinaryNotFoundError();
|
|
1271
|
-
};
|
|
1272
|
-
DefaultAuthParameters.prototype.SetRequestedScopes = function () {
|
|
1273
|
-
throw getBinaryNotFoundError();
|
|
1274
|
-
};
|
|
1275
|
-
DefaultAuthParameters.prototype.SetDecodedClaims = function () {
|
|
1276
|
-
throw getBinaryNotFoundError();
|
|
1277
|
-
};
|
|
1278
|
-
DefaultAuthParameters.prototype.SetAccessTokenToRenew = function () {
|
|
1279
|
-
throw getBinaryNotFoundError();
|
|
1280
|
-
};
|
|
1281
|
-
DefaultAuthParameters.prototype.SetPopParams = function () {
|
|
1282
|
-
throw getBinaryNotFoundError();
|
|
1283
|
-
};
|
|
1284
|
-
DefaultAuthParameters.prototype.SetAdditionalParameter = function () {
|
|
1285
|
-
throw getBinaryNotFoundError();
|
|
1286
|
-
};
|
|
1287
|
-
return DefaultAuthParameters;
|
|
1288
|
-
}());
|
|
1289
|
-
var DefaultMsalNodeRuntime = /** @class */ (function () {
|
|
1290
|
-
function DefaultMsalNodeRuntime() {
|
|
1291
|
-
this.AuthParameters = DefaultAuthParameters;
|
|
1292
|
-
this.StartupError = getBinaryNotFoundError();
|
|
1293
|
-
}
|
|
1294
|
-
DefaultMsalNodeRuntime.prototype.ReadAccountByIdAsync = function () {
|
|
1295
|
-
throw getBinaryNotFoundError();
|
|
1296
|
-
};
|
|
1297
|
-
DefaultMsalNodeRuntime.prototype.SignInAsync = function () {
|
|
1298
|
-
throw getBinaryNotFoundError();
|
|
1299
|
-
};
|
|
1300
|
-
DefaultMsalNodeRuntime.prototype.SignInSilentlyAsync = function () {
|
|
1301
|
-
throw getBinaryNotFoundError();
|
|
1302
|
-
};
|
|
1303
|
-
DefaultMsalNodeRuntime.prototype.SignInInteractivelyAsync = function () {
|
|
1304
|
-
throw getBinaryNotFoundError();
|
|
1305
|
-
};
|
|
1306
|
-
DefaultMsalNodeRuntime.prototype.AcquireTokenSilentlyAsync = function () {
|
|
1307
|
-
throw getBinaryNotFoundError();
|
|
1308
|
-
};
|
|
1309
|
-
DefaultMsalNodeRuntime.prototype.AcquireTokenInteractivelyAsync = function () {
|
|
1310
|
-
throw getBinaryNotFoundError();
|
|
1311
|
-
};
|
|
1312
|
-
DefaultMsalNodeRuntime.prototype.SignOutSilentlyAsync = function () {
|
|
1313
|
-
throw getBinaryNotFoundError();
|
|
1314
|
-
};
|
|
1315
|
-
DefaultMsalNodeRuntime.prototype.RegisterLogger = function () {
|
|
1316
|
-
throw getBinaryNotFoundError();
|
|
1317
|
-
};
|
|
1318
|
-
DefaultMsalNodeRuntime.prototype.DiscoverAccountsAsync = function () {
|
|
1319
|
-
throw getBinaryNotFoundError();
|
|
1320
|
-
};
|
|
1321
|
-
return DefaultMsalNodeRuntime;
|
|
1322
|
-
}());
|
|
1323
|
-
var msalNodeRuntime;
|
|
1324
|
-
try {
|
|
1325
|
-
msalNodeRuntime = require("./msal-node-runtime");
|
|
1326
|
-
}
|
|
1327
|
-
catch (_a) {
|
|
1328
|
-
// If DLLs can't be loaded export stub class instance to prevent static imports from throwing
|
|
1329
|
-
msalNodeRuntime = new DefaultMsalNodeRuntime();
|
|
1330
|
-
}
|
|
1331
|
-
|
|
1332
|
-
/**
|
|
1333
|
-
* Resolves the directory path for storing the authentication cache.
|
|
1334
|
-
*
|
|
1335
|
-
* Uses the user's root directory if available, otherwise falls back to the OS temp directory.
|
|
1336
|
-
*
|
|
1337
|
-
* @returns The resolved cache directory path as a string.
|
|
1338
|
-
*/
|
|
1339
|
-
const resolveCachePath = () => {
|
|
1340
|
-
return Environment?.getUserRootDirectory() ?? tmpdir();
|
|
1341
|
-
};
|
|
1342
|
-
/**
|
|
1343
|
-
* Resolves the file path for the authentication cache based on tenant and client IDs.
|
|
1344
|
-
*
|
|
1345
|
-
* @param tenantId - The Azure AD tenant ID.
|
|
1346
|
-
* @param clientId - The Azure AD client/application ID.
|
|
1347
|
-
* @returns The full file path for the cache file.
|
|
1348
|
-
*/
|
|
1349
|
-
const resolveCacheFilePath = (tenantId, clientId) => {
|
|
1350
|
-
return path$1.join(resolveCachePath(), `.token-cache-${tenantId}_${clientId}`);
|
|
1351
|
-
};
|
|
1352
|
-
/**
|
|
1353
|
-
* Creates a persistence cache for storing authentication data securely on disk.
|
|
1354
|
-
*
|
|
1355
|
-
* The cache is encrypted and scoped to the current user for security. It is uniquely identified
|
|
1356
|
-
* by the provided tenant and client IDs, and is associated with the 'fusion-framework' service.
|
|
1357
|
-
*
|
|
1358
|
-
* @param tenantId - The Azure AD tenant ID used to identify the cache.
|
|
1359
|
-
* @param clientId - The Azure AD client/application ID used to identify the cache.
|
|
1360
|
-
* @returns A promise that resolves to the created persistence cache instance.
|
|
1361
|
-
*/
|
|
1362
|
-
const createPersistenceCache = async (tenantId, clientId) => {
|
|
1363
|
-
return PersistenceCreator.createPersistence({
|
|
1364
|
-
cachePath: resolveCacheFilePath(tenantId, clientId),
|
|
1365
|
-
serviceName: 'fusion-framework',
|
|
1366
|
-
accountName: [tenantId, clientId].join('_'),
|
|
1367
|
-
dataProtectionScope: DataProtectionScope.CurrentUser,
|
|
1368
|
-
});
|
|
1369
|
-
};
|
|
1370
|
-
/**
|
|
1371
|
-
* Creates a `PersistenceCachePlugin` instance for use with MSAL, using the provided tenant and client IDs.
|
|
1372
|
-
*
|
|
1373
|
-
* This plugin enables MSAL to use the secure persistence cache for token storage.
|
|
1374
|
-
*
|
|
1375
|
-
* @param tenantId - The Azure AD tenant ID.
|
|
1376
|
-
* @param clientId - The Azure AD client/application ID.
|
|
1377
|
-
* @returns A promise that resolves to an instance of `PersistenceCachePlugin`.
|
|
1378
|
-
*/
|
|
1379
|
-
const createPersistenceCachePlugin = async (tenantId, clientId) => {
|
|
1380
|
-
return new PersistenceCachePlugin(await createPersistenceCache(tenantId, clientId));
|
|
1381
|
-
};
|
|
1382
|
-
|
|
1383
|
-
/**
|
|
1384
|
-
* Creates and configures a new MSAL PublicClientApplication instance for Azure AD authentication.
|
|
1385
|
-
*
|
|
1386
|
-
* This function sets up the client with the specified tenant and client IDs, and attaches a secure
|
|
1387
|
-
* persistence cache plugin for storing authentication tokens on disk. The resulting client can be used
|
|
1388
|
-
* for both silent and interactive authentication flows, depending on how it is integrated.
|
|
1389
|
-
*
|
|
1390
|
-
* @param tenantId - The Azure Active Directory tenant ID (directory identifier).
|
|
1391
|
-
* @param clientId - The client/application ID registered in Azure AD.
|
|
1392
|
-
* @returns A Promise that resolves to a configured instance of `PublicClientApplication`.
|
|
1393
|
-
*
|
|
1394
|
-
* @remarks
|
|
1395
|
-
* The returned client uses a secure, user-scoped cache for token storage. This is recommended for CLI tools,
|
|
1396
|
-
* background services, and other Node.js applications that require persistent authentication.
|
|
1397
|
-
*
|
|
1398
|
-
* @example
|
|
1399
|
-
* ```typescript
|
|
1400
|
-
* const client = await createAuthClient('your-tenant-id', 'your-client-id');
|
|
1401
|
-
* // Use the client with MSAL APIs for authentication flows
|
|
1402
|
-
* ```
|
|
1403
|
-
*/
|
|
1404
|
-
const createAuthClient = async (tenantId, clientId) => {
|
|
1405
|
-
const cachePlugin = await createPersistenceCachePlugin(tenantId, clientId);
|
|
1406
|
-
return new PublicClientApplication({
|
|
1407
|
-
auth: {
|
|
1408
|
-
clientId: clientId,
|
|
1409
|
-
authority: `https://login.microsoftonline.com/${tenantId}`,
|
|
1410
|
-
},
|
|
1411
|
-
cache: { cachePlugin },
|
|
1412
|
-
});
|
|
1413
|
-
};
|
|
1414
|
-
|
|
1415
|
-
export { createAuthClient, createAuthClient as default };
|