@adobe/helix-onedrive-support 12.3.11 → 12.4.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 +14 -0
- package/package.json +6 -6
- package/src/index.js +2 -0
- package/src/sanitizeCache.js +87 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## [12.4.1](https://github.com/adobe/helix-onedrive-support/compare/v12.4.0...v12.4.1) (2026-06-23)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **deps:** update external fixes ([#759](https://github.com/adobe/helix-onedrive-support/issues/759)) ([5b86e2b](https://github.com/adobe/helix-onedrive-support/commit/5b86e2b083c9d592bd2730c04a7a66aad8a3ecdd))
|
|
7
|
+
|
|
8
|
+
# [12.4.0](https://github.com/adobe/helix-onedrive-support/compare/v12.3.11...v12.4.0) (2026-06-11)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* add sanitizeCache to repair MSAL refresh-token cache key mismatches ([#757](https://github.com/adobe/helix-onedrive-support/issues/757)) ([077d05a](https://github.com/adobe/helix-onedrive-support/commit/077d05a28d3d7e87f18281bd933bea049d6978ee))
|
|
14
|
+
|
|
1
15
|
## [12.3.11](https://github.com/adobe/helix-onedrive-support/compare/v12.3.10...v12.3.11) (2026-06-08)
|
|
2
16
|
|
|
3
17
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/helix-onedrive-support",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.4.1",
|
|
4
4
|
"description": "Helix OneDrive Support",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -30,13 +30,13 @@
|
|
|
30
30
|
"@adobe/fetch": "^4.2.3",
|
|
31
31
|
"@adobe/helix-shared-string": "^2.1.0",
|
|
32
32
|
"@adobe/helix-shared-tokencache": "^1.4.19",
|
|
33
|
-
"@azure/msal-common": "16.
|
|
34
|
-
"@azure/msal-node": "5.2.
|
|
33
|
+
"@azure/msal-common": "16.7.0",
|
|
34
|
+
"@azure/msal-node": "5.2.3",
|
|
35
35
|
"jose": "6.2.3"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@adobe/eslint-config-helix": "3.0.28",
|
|
39
|
-
"@aws-sdk/client-s3": "3.
|
|
39
|
+
"@aws-sdk/client-s3": "3.1064.0",
|
|
40
40
|
"@eslint/config-helpers": "0.6.0",
|
|
41
41
|
"@semantic-release/changelog": "6.0.3",
|
|
42
42
|
"@semantic-release/git": "10.0.1",
|
|
@@ -50,12 +50,12 @@
|
|
|
50
50
|
"jsdoc-to-markdown": "9.1.3",
|
|
51
51
|
"jsdoc-tsimport-plugin": "1.0.5",
|
|
52
52
|
"junit-report-builder": "5.1.2",
|
|
53
|
-
"lint-staged": "17.0.
|
|
53
|
+
"lint-staged": "17.0.7",
|
|
54
54
|
"mocha": "11.7.6",
|
|
55
55
|
"mocha-multi-reporters": "1.5.1",
|
|
56
56
|
"mocha-suppress-logs": "0.6.0",
|
|
57
57
|
"nock": "14.0.15",
|
|
58
|
-
"npm": "11.
|
|
58
|
+
"npm": "11.16.0",
|
|
59
59
|
"semantic-release": "25.0.3"
|
|
60
60
|
},
|
|
61
61
|
"lint-staged": {
|
package/src/index.js
CHANGED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
// internals is not part of MSAL's public API — pin @azure/msal-node tightly
|
|
14
|
+
// and revisit if Deserializer is ever exposed publicly.
|
|
15
|
+
import { internals } from '@azure/msal-node';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Derives the canonical MSAL cache key for a refresh token, matching the
|
|
19
|
+
* format used by MSAL's internal serializer: segments are joined with `-` and
|
|
20
|
+
* lowercased. Empty realm, target, and tokenType segments are included to keep
|
|
21
|
+
* the key structure consistent with all other credential types.
|
|
22
|
+
*
|
|
23
|
+
* @param {object} refreshToken deserialized MSAL refresh-token entry
|
|
24
|
+
* @param {string} refreshToken.homeAccountId account identifier
|
|
25
|
+
* @param {string} refreshToken.environment authority host (e.g. `login.microsoftonline.com`)
|
|
26
|
+
* @param {string} refreshToken.credentialType always `"RefreshToken"` for this entry type
|
|
27
|
+
* @param {string} [refreshToken.familyId] family ID for first-party apps; takes precedence over
|
|
28
|
+
* clientId
|
|
29
|
+
* @param {string} refreshToken.clientId application client ID
|
|
30
|
+
* @returns {string} lowercase hyphen-joined cache key
|
|
31
|
+
*/
|
|
32
|
+
function generateKey(refreshToken) {
|
|
33
|
+
const {
|
|
34
|
+
homeAccountId, environment, credentialType, familyId, clientId,
|
|
35
|
+
} = refreshToken;
|
|
36
|
+
const credentialKey = [
|
|
37
|
+
homeAccountId,
|
|
38
|
+
environment,
|
|
39
|
+
credentialType,
|
|
40
|
+
familyId || clientId, // first-party apps share a family token; fall back to clientId
|
|
41
|
+
'', // realm
|
|
42
|
+
'', // target
|
|
43
|
+
'', // tokenType
|
|
44
|
+
];
|
|
45
|
+
return credentialKey.join('-').toLowerCase();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Removes refresh-token entries whose cache key no longer matches the key that
|
|
50
|
+
* MSAL would generate for them today. This repairs caches that were written by
|
|
51
|
+
* an older MSAL version using a different key scheme.
|
|
52
|
+
*
|
|
53
|
+
* Mutates {@link data}.RefreshToken in place.
|
|
54
|
+
*
|
|
55
|
+
* If all tokens are outdated the cache is left untouched and a warning is
|
|
56
|
+
* logged, because wiping every token would sign out all active sessions.
|
|
57
|
+
*
|
|
58
|
+
* @param {object} data raw MSAL serialized cache (JSON-parsed)
|
|
59
|
+
* @param {{ info: Function, warn: Function }} log logger instance
|
|
60
|
+
*/
|
|
61
|
+
export function sanitizeCache(data, log) {
|
|
62
|
+
const deserialized = internals.Deserializer.deserializeAllCache(data);
|
|
63
|
+
const { refreshTokens } = deserialized;
|
|
64
|
+
|
|
65
|
+
const outdatedKeys = [];
|
|
66
|
+
for (const [actualKey, refreshToken] of Object.entries(refreshTokens)) {
|
|
67
|
+
const expectedKey = generateKey(refreshToken);
|
|
68
|
+
if (actualKey !== expectedKey) {
|
|
69
|
+
outdatedKeys.push(actualKey);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (outdatedKeys.length === 0) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// If every token is outdated the key scheme itself probably changed; removing
|
|
77
|
+
// them all would revoke all sessions, so bail out and let the caller decide.
|
|
78
|
+
if (Object.keys(refreshTokens).length === outdatedKeys.length) {
|
|
79
|
+
log.warn('All refresh tokens have an unexpected key, generation might have changed.');
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
for (const key of outdatedKeys) {
|
|
84
|
+
delete data.RefreshToken[key];
|
|
85
|
+
log.info(`Removed RefreshToken with key: ${key}`);
|
|
86
|
+
}
|
|
87
|
+
}
|