@adobe/helix-config-storage 1.3.2 → 1.5.0
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 +1 -1
- package/src/config-store.js +25 -7
- package/src/schemas/org.schema.json +3 -0
- package/src/transient-token-store.js +40 -34
- package/types/org-config.d.ts +12 -0
- package/types/profile-config.d.ts +1 -0
- package/types/site-config.d.ts +1 -0
- package/validate-json-schemas.sh +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [1.5.0](https://github.com/adobe/helix-config-storage/compare/v1.4.0...v1.5.0) (2024-09-02)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* restructure transient-site-tokens ([#15](https://github.com/adobe/helix-config-storage/issues/15)) ([bec495c](https://github.com/adobe/helix-config-storage/commit/bec495cf3b594d38f0f2586fc3addba457be684f))
|
|
7
|
+
|
|
8
|
+
# [1.4.0](https://github.com/adobe/helix-config-storage/compare/v1.3.2...v1.4.0) (2024-08-31)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* allow adding several users ([cc0722d](https://github.com/adobe/helix-config-storage/commit/cc0722d35b7dc75e78926922c9e9b1a55bbc8377))
|
|
14
|
+
|
|
1
15
|
## [1.3.2](https://github.com/adobe/helix-config-storage/compare/v1.3.1...v1.3.2) (2024-08-31)
|
|
2
16
|
|
|
3
17
|
|
package/package.json
CHANGED
package/src/config-store.js
CHANGED
|
@@ -68,6 +68,13 @@ const FRAGMENTS = {
|
|
|
68
68
|
},
|
|
69
69
|
profiles: FRAGMENTS_COMMON,
|
|
70
70
|
org: {
|
|
71
|
+
tokens: {
|
|
72
|
+
'.': 'tokens',
|
|
73
|
+
'.param': {
|
|
74
|
+
name: 'id',
|
|
75
|
+
'.': 'token',
|
|
76
|
+
},
|
|
77
|
+
},
|
|
71
78
|
users: {
|
|
72
79
|
'.': 'users',
|
|
73
80
|
'.param': {
|
|
@@ -353,17 +360,28 @@ export class ConfigStore {
|
|
|
353
360
|
// don't expose hash in return value
|
|
354
361
|
delete ret.hash;
|
|
355
362
|
} else if (frag.type === 'users') {
|
|
356
|
-
const user = createUser();
|
|
357
|
-
data = {
|
|
358
|
-
...data,
|
|
359
|
-
...user,
|
|
360
|
-
};
|
|
361
|
-
relPath = ['users', user.id];
|
|
362
|
-
frag.type = 'user';
|
|
363
363
|
// todo: define via "schema"
|
|
364
364
|
if (!old.users) {
|
|
365
365
|
old.users = [];
|
|
366
366
|
}
|
|
367
|
+
if (Array.isArray(data)) {
|
|
368
|
+
const users = [...old.users];
|
|
369
|
+
for (const userData of data) {
|
|
370
|
+
users.push({
|
|
371
|
+
...createUser(),
|
|
372
|
+
...userData,
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
data = users;
|
|
376
|
+
} else {
|
|
377
|
+
const user = createUser();
|
|
378
|
+
data = {
|
|
379
|
+
...data,
|
|
380
|
+
...user,
|
|
381
|
+
};
|
|
382
|
+
relPath = ['users', user.id];
|
|
383
|
+
frag.type = 'user';
|
|
384
|
+
}
|
|
367
385
|
} else if (frag.type === 'user') {
|
|
368
386
|
const user = deepGetOrCreate(old, relPath);
|
|
369
387
|
if (!user) {
|
|
@@ -14,9 +14,7 @@
|
|
|
14
14
|
* @typedef Token
|
|
15
15
|
* @property {string} id
|
|
16
16
|
* @property {string} value
|
|
17
|
-
* @property {string} hash
|
|
18
17
|
* @property {Date} created
|
|
19
|
-
* @property {Date} expires
|
|
20
18
|
*/
|
|
21
19
|
|
|
22
20
|
/**
|
|
@@ -25,20 +23,8 @@
|
|
|
25
23
|
* @property {Token} live
|
|
26
24
|
*/
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
* @typedef SiteTokensData
|
|
30
|
-
* @property {Token[]} preview
|
|
31
|
-
* @property {Token[]} live
|
|
32
|
-
*/
|
|
33
|
-
|
|
26
|
+
import crypto from 'crypto';
|
|
34
27
|
import { HelixStorage } from '@adobe/helix-shared-storage';
|
|
35
|
-
import { createToken } from './utils.js';
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Default expiry time for transient site tokens (24 hours)
|
|
39
|
-
* @type {number}
|
|
40
|
-
*/
|
|
41
|
-
const DEFAULT_EXPIRY_TIME = 24 * 60 * 60 * 1000;
|
|
42
28
|
|
|
43
29
|
/**
|
|
44
30
|
* Store to manage transient site tokens.
|
|
@@ -80,12 +66,12 @@ export class TransientTokenStore {
|
|
|
80
66
|
this.org = org;
|
|
81
67
|
this.site = site;
|
|
82
68
|
this.#key = `orgs/${this.org}/sites/${this.site}/transient-site-tokens.json`;
|
|
83
|
-
this.#now = Date
|
|
69
|
+
this.#now = new Date();
|
|
84
70
|
}
|
|
85
71
|
|
|
86
72
|
/**
|
|
87
73
|
* Returns the current time (mainly used for tests)
|
|
88
|
-
* @returns {
|
|
74
|
+
* @returns {Date}
|
|
89
75
|
*/
|
|
90
76
|
now() {
|
|
91
77
|
return this.#now;
|
|
@@ -94,22 +80,21 @@ export class TransientTokenStore {
|
|
|
94
80
|
/**
|
|
95
81
|
* Loads the transient site tokens from the storage
|
|
96
82
|
* @param ctx
|
|
97
|
-
* @returns {Promise<
|
|
83
|
+
* @returns {Promise<SiteTokens>}
|
|
98
84
|
*/
|
|
99
85
|
async #load(ctx) {
|
|
100
86
|
if (!this.#tokens) {
|
|
101
87
|
this.#tokens = {
|
|
102
|
-
preview:
|
|
103
|
-
live:
|
|
88
|
+
preview: undefined,
|
|
89
|
+
live: undefined,
|
|
104
90
|
};
|
|
105
91
|
this.#modified = false;
|
|
106
92
|
const storage = HelixStorage.fromContext(ctx).configBus();
|
|
107
93
|
const buf = await storage.get(this.#key);
|
|
108
94
|
if (buf) {
|
|
109
95
|
const data = JSON.parse(buf.toString('utf-8'));
|
|
110
|
-
|
|
111
|
-
this.#tokens.
|
|
112
|
-
this.#tokens.live = data.tokens.live.filter(isValid);
|
|
96
|
+
this.#tokens.preview = data.tokens.preview;
|
|
97
|
+
this.#tokens.live = data.tokens.live;
|
|
113
98
|
}
|
|
114
99
|
}
|
|
115
100
|
return this.#tokens;
|
|
@@ -140,12 +125,17 @@ export class TransientTokenStore {
|
|
|
140
125
|
throw new Error(`Invalid partition: ${partition}`);
|
|
141
126
|
}
|
|
142
127
|
const tokens = await this.#load(ctx);
|
|
143
|
-
let token = tokens[partition]
|
|
128
|
+
let token = tokens[partition];
|
|
144
129
|
if (!token) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
130
|
+
const value = crypto.randomBytes(32).toString('base64url');
|
|
131
|
+
const id = crypto.createHash('sha256').update(value).digest().toString('base64url');
|
|
132
|
+
const created = this.#now.toUTCString();
|
|
133
|
+
token = {
|
|
134
|
+
id,
|
|
135
|
+
value,
|
|
136
|
+
created,
|
|
137
|
+
};
|
|
138
|
+
tokens[partition] = token;
|
|
149
139
|
this.#modified = true;
|
|
150
140
|
}
|
|
151
141
|
await this.#save(ctx);
|
|
@@ -153,15 +143,31 @@ export class TransientTokenStore {
|
|
|
153
143
|
}
|
|
154
144
|
|
|
155
145
|
/**
|
|
156
|
-
* Returns the
|
|
146
|
+
* Returns the token header values for the given user id.
|
|
147
|
+
* @param ctx
|
|
148
|
+
* @param partition
|
|
149
|
+
* @param userid
|
|
150
|
+
* @returns {Promise<string>}
|
|
151
|
+
*/
|
|
152
|
+
async getTokenHeader(ctx, partition, userid) {
|
|
153
|
+
const token = await this.getOrCreateToken(ctx, partition);
|
|
154
|
+
const user64 = Buffer.from(userid)
|
|
155
|
+
.toString('base64url');
|
|
156
|
+
const key = `${user64};${this.#now.toISOString().split('T')[0]}`;
|
|
157
|
+
const hash = crypto
|
|
158
|
+
.createHmac('sha512', key)
|
|
159
|
+
.update(token.value, 'utf-8')
|
|
160
|
+
.digest()
|
|
161
|
+
.toString('base64url');
|
|
162
|
+
return `hlxtst_${hash};${user64}`;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Returns the transient site tokens
|
|
157
167
|
* @param ctx
|
|
158
168
|
* @returns {Promise<SiteTokens>}
|
|
159
169
|
*/
|
|
160
170
|
async getSiteTokens(ctx) {
|
|
161
|
-
|
|
162
|
-
return {
|
|
163
|
-
preview: tokens.preview[0],
|
|
164
|
-
live: tokens.live[0],
|
|
165
|
-
};
|
|
171
|
+
return this.#load(ctx);
|
|
166
172
|
}
|
|
167
173
|
}
|
package/types/org-config.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export interface HelixOrgConfig {
|
|
|
26
26
|
description?: string;
|
|
27
27
|
users?: Users;
|
|
28
28
|
groups?: Groups;
|
|
29
|
+
tokens?: Tokens;
|
|
29
30
|
}
|
|
30
31
|
export interface User {
|
|
31
32
|
id: string;
|
|
@@ -49,3 +50,14 @@ export interface Group {
|
|
|
49
50
|
[k: string]: unknown;
|
|
50
51
|
}[];
|
|
51
52
|
}
|
|
53
|
+
export interface Tokens {
|
|
54
|
+
/**
|
|
55
|
+
* This interface was referenced by `Tokens`'s JSON-Schema definition
|
|
56
|
+
* via the `patternProperty` "^[a-zA-Z0-9-_=]+$".
|
|
57
|
+
*/
|
|
58
|
+
[k: string]: {
|
|
59
|
+
id?: string;
|
|
60
|
+
hash?: string;
|
|
61
|
+
created?: string;
|
|
62
|
+
};
|
|
63
|
+
}
|
package/types/site-config.d.ts
CHANGED
package/validate-json-schemas.sh
CHANGED
|
@@ -21,8 +21,8 @@ npx ajv-cli --spec=draft2019 -c ajv-formats compile \
|
|
|
21
21
|
-s src/schemas/metadata-source.schema.json \
|
|
22
22
|
-s src/schemas/user.schema.json \
|
|
23
23
|
-s src/schemas/users.schema.json \
|
|
24
|
-
-s src/schemas/org.schema.json \
|
|
25
24
|
-s src/schemas/tokens.schema.json \
|
|
25
|
+
-s src/schemas/org.schema.json \
|
|
26
26
|
-s src/schemas/sidekick.schema.json \
|
|
27
27
|
-s src/schemas/robots.schema.json \
|
|
28
28
|
-s src/schemas/public.schema.json \
|