@adobe/helix-config-storage 1.7.2 → 1.7.4
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 +7 -7
- package/src/index.js +0 -1
- package/src/transient-token-store.js +0 -181
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## [1.7.4](https://github.com/adobe/helix-config-storage/compare/v1.7.3...v1.7.4) (2024-09-21)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **deps:** update dependency @adobe/fetch to v4.1.9 ([cdd230d](https://github.com/adobe/helix-config-storage/commit/cdd230d259dbbcae87ab290f2615c4d1a7649a24))
|
|
7
|
+
|
|
8
|
+
## [1.7.3](https://github.com/adobe/helix-config-storage/compare/v1.7.2...v1.7.3) (2024-09-13)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* remove transient site token store ([#27](https://github.com/adobe/helix-config-storage/issues/27)) ([adb1543](https://github.com/adobe/helix-config-storage/commit/adb15437ba334ea3fe7276d4c9f4c0b785b736a3))
|
|
14
|
+
|
|
1
15
|
## [1.7.2](https://github.com/adobe/helix-config-storage/compare/v1.7.1...v1.7.2) (2024-09-07)
|
|
2
16
|
|
|
3
17
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/helix-config-storage",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.4",
|
|
4
4
|
"description": "Helix Config Storage",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "src/index.d.ts",
|
|
@@ -42,16 +42,16 @@
|
|
|
42
42
|
"@semantic-release/npm": "12.0.1",
|
|
43
43
|
"ajv-cli": "5.0.0",
|
|
44
44
|
"c8": "10.1.2",
|
|
45
|
-
"eslint": "8.57.
|
|
46
|
-
"husky": "9.1.
|
|
45
|
+
"eslint": "8.57.1",
|
|
46
|
+
"husky": "9.1.6",
|
|
47
47
|
"json-schema-to-typescript": "15.0.2",
|
|
48
|
-
"junit-report-builder": "5.
|
|
48
|
+
"junit-report-builder": "5.1.1",
|
|
49
49
|
"lint-staged": "15.2.10",
|
|
50
50
|
"mocha": "10.7.3",
|
|
51
51
|
"mocha-multi-reporters": "1.5.1",
|
|
52
52
|
"mocha-suppress-logs": "0.5.1",
|
|
53
53
|
"nock": "13.5.5",
|
|
54
|
-
"semantic-release": "24.1.
|
|
54
|
+
"semantic-release": "24.1.1",
|
|
55
55
|
"xml2js": "0.6.2"
|
|
56
56
|
},
|
|
57
57
|
"lint-staged": {
|
|
@@ -59,13 +59,13 @@
|
|
|
59
59
|
"*.cjs": "eslint"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@adobe/fetch": "4.1.
|
|
62
|
+
"@adobe/fetch": "4.1.9",
|
|
63
63
|
"@adobe/helix-shared-config": "10.6.8",
|
|
64
64
|
"@adobe/helix-shared-git": "3.0.14",
|
|
65
65
|
"@adobe/helix-shared-storage": "1.0.6",
|
|
66
66
|
"@adobe/helix-shared-utils": "3.0.2",
|
|
67
67
|
"ajv": "8.17.1",
|
|
68
68
|
"ajv-formats": "3.0.1",
|
|
69
|
-
"jose": "5.
|
|
69
|
+
"jose": "5.9.2"
|
|
70
70
|
}
|
|
71
71
|
}
|
package/src/index.js
CHANGED
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright 2024 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
|
-
/**
|
|
14
|
-
* @typedef Token
|
|
15
|
-
* @property {string} id
|
|
16
|
-
* @property {string} value
|
|
17
|
-
* @property {Date} created
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* @typedef SiteTokens
|
|
22
|
-
* @property {Token} preview
|
|
23
|
-
* @property {Token} live
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
import crypto from 'crypto';
|
|
27
|
-
import { HelixStorage } from '@adobe/helix-shared-storage';
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Store to manage transient site tokens.
|
|
31
|
-
* - the tokens have a fixed expiration time (default 24h) which can be verified on the edge
|
|
32
|
-
* - the transient site tokens are managed and delivered independent of the fixed site tokens
|
|
33
|
-
*/
|
|
34
|
-
export class TransientTokenStore {
|
|
35
|
-
/**
|
|
36
|
-
* Org name
|
|
37
|
-
*/
|
|
38
|
-
org;
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Site name
|
|
42
|
-
*/
|
|
43
|
-
site;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* S3/R2 Key for the transient site tokens
|
|
47
|
-
*/
|
|
48
|
-
#key;
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* loaded tokens
|
|
52
|
-
*/
|
|
53
|
-
#tokens;
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* modified flag
|
|
57
|
-
*/
|
|
58
|
-
#modified;
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* flag indicating that the store was modified
|
|
62
|
-
*/
|
|
63
|
-
wasModified = false;
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* consistent "now"
|
|
67
|
-
*/
|
|
68
|
-
#now;
|
|
69
|
-
|
|
70
|
-
constructor(org, site) {
|
|
71
|
-
this.org = org;
|
|
72
|
-
this.site = site;
|
|
73
|
-
this.#key = `orgs/${this.org}/sites/${this.site}/transient-site-tokens.json`;
|
|
74
|
-
this.#now = new Date();
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Returns the current time (mainly used for tests)
|
|
79
|
-
* @returns {Date}
|
|
80
|
-
*/
|
|
81
|
-
now() {
|
|
82
|
-
return this.#now;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Loads the transient site tokens from the storage
|
|
87
|
-
* @param ctx
|
|
88
|
-
* @returns {Promise<SiteTokens>}
|
|
89
|
-
*/
|
|
90
|
-
async #load(ctx) {
|
|
91
|
-
if (!this.#tokens) {
|
|
92
|
-
this.#tokens = {
|
|
93
|
-
preview: undefined,
|
|
94
|
-
live: undefined,
|
|
95
|
-
};
|
|
96
|
-
this.#modified = false;
|
|
97
|
-
const storage = HelixStorage.fromContext(ctx).configBus();
|
|
98
|
-
const buf = await storage.get(this.#key);
|
|
99
|
-
if (buf) {
|
|
100
|
-
const data = JSON.parse(buf.toString('utf-8'));
|
|
101
|
-
this.#tokens.preview = data.tokens.preview;
|
|
102
|
-
this.#tokens.live = data.tokens.live;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
return this.#tokens;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Saves the transient site tokens to the storage if modified
|
|
110
|
-
* @param ctx
|
|
111
|
-
* @returns {Promise<void>}
|
|
112
|
-
*/
|
|
113
|
-
async #save(ctx) {
|
|
114
|
-
if (this.#modified) {
|
|
115
|
-
const storage = HelixStorage.fromContext(ctx).configBus();
|
|
116
|
-
await storage.put(this.#key, JSON.stringify({
|
|
117
|
-
tokens: this.#tokens,
|
|
118
|
-
}));
|
|
119
|
-
this.#modified = false;
|
|
120
|
-
this.wasModified = true;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Returns the transient site token for the given partition. If the token does not exist or is
|
|
126
|
-
* expired, it will be created.
|
|
127
|
-
* @param ctx
|
|
128
|
-
* @param partition
|
|
129
|
-
* @returns {Promise<Token>}
|
|
130
|
-
*/
|
|
131
|
-
async getOrCreateToken(ctx, partition) {
|
|
132
|
-
if (partition !== 'preview' && partition !== 'live') {
|
|
133
|
-
throw new Error(`Invalid partition: ${partition}`);
|
|
134
|
-
}
|
|
135
|
-
const tokens = await this.#load(ctx);
|
|
136
|
-
let token = tokens[partition];
|
|
137
|
-
if (!token) {
|
|
138
|
-
const value = crypto.randomBytes(32).toString('base64url');
|
|
139
|
-
const id = crypto.createHash('sha256').update(value).digest().toString('base64url');
|
|
140
|
-
const created = this.#now.toUTCString();
|
|
141
|
-
token = {
|
|
142
|
-
id,
|
|
143
|
-
value,
|
|
144
|
-
created,
|
|
145
|
-
};
|
|
146
|
-
tokens[partition] = token;
|
|
147
|
-
this.#modified = true;
|
|
148
|
-
}
|
|
149
|
-
await this.#save(ctx);
|
|
150
|
-
return token;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Returns the token header values for the given user id.
|
|
155
|
-
* @param ctx
|
|
156
|
-
* @param partition
|
|
157
|
-
* @param userid
|
|
158
|
-
* @returns {Promise<string>}
|
|
159
|
-
*/
|
|
160
|
-
async getTokenHeader(ctx, partition, userid) {
|
|
161
|
-
const token = await this.getOrCreateToken(ctx, partition);
|
|
162
|
-
const user64 = Buffer.from(userid)
|
|
163
|
-
.toString('base64url');
|
|
164
|
-
const key = `${user64};${this.#now.toISOString().split('T')[0]}`;
|
|
165
|
-
const hash = crypto
|
|
166
|
-
.createHmac('sha512', key)
|
|
167
|
-
.update(token.value, 'utf-8')
|
|
168
|
-
.digest()
|
|
169
|
-
.toString('base64url');
|
|
170
|
-
return `hlxtst_${hash};${user64}`;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Returns the transient site tokens
|
|
175
|
-
* @param ctx
|
|
176
|
-
* @returns {Promise<SiteTokens>}
|
|
177
|
-
*/
|
|
178
|
-
async getSiteTokens(ctx) {
|
|
179
|
-
return this.#load(ctx);
|
|
180
|
-
}
|
|
181
|
-
}
|