@forestadmin/agent-bff 1.1.0 → 1.2.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/README.md CHANGED
@@ -43,6 +43,25 @@ yarn start:dev # node --env-file=.env dist/cli.js
43
43
  - A required var that is absent (or empty / whitespace-only) does not crash the server. It boots and
44
44
  reports the gap through `/health` (503 `degraded`).
45
45
 
46
+ ## Sessions & token rotation
47
+
48
+ OAuth sessions, opaque refresh tokens, and rotated-out-token reuse detection are held in an
49
+ **in-memory, single-process** store. Reuse detection has a one-step grace window: re-presenting the
50
+ **most recently** rotated-out token (a benign retry of a refresh whose response was lost) replays
51
+ the last issued pair instead of killing the session — the stored refresh token is returned with a
52
+ freshly minted access JWT. Re-presenting any **older** rotated-out token still invalidates the whole
53
+ session, so a stolen earlier token stays detectable. The grace window is bounded by the rotation
54
+ chain, not a timer: once the client advances one more rotation, the previous token is no longer the
55
+ latest and falls back to reuse. These guarantees are only correct within one process. Two layers
56
+ are process-local: the session/rotation maps in the store, and the in-flight refresh dedup maps
57
+ (`inFlightRefreshByPresentedHash` in `oauth-routes`, `inFlightRefreshesBySid` in
58
+ `session-lifecycle`) that collapse concurrent refreshes of the same token into a single rotation.
59
+ Running the BFF behind a load balancer without sticky sessions breaks reuse detection and the
60
+ single-rotation guarantee — and a shared session store alone does not fix it: two concurrent
61
+ refreshes landing on different nodes would each try to rotate, one committing and the other failing
62
+ with `session_expired`. Horizontal scaling requires both a shared session store **and** a shared
63
+ (or node-pinned) refresh-coordination mechanism.
64
+
46
65
  ## `/health`
47
66
 
48
67
  ```jsonc
@@ -14,5 +14,6 @@ export declare function invalidGrant(message: string): OAuthRequestError;
14
14
  export declare function unsupportedGrantType(message: string): OAuthRequestError;
15
15
  export declare function forestIdentityNotAllowed(message: string): OAuthRequestError;
16
16
  export declare function sessionExpired(message: string): OAuthRequestError;
17
+ export declare function sessionInvalidated(message: string): OAuthRequestError;
17
18
  export declare function serverError(message: string): OAuthRequestError;
18
19
  //# sourceMappingURL=oauth-error.d.ts.map
@@ -8,6 +8,7 @@ exports.invalidGrant = invalidGrant;
8
8
  exports.unsupportedGrantType = unsupportedGrantType;
9
9
  exports.forestIdentityNotAllowed = forestIdentityNotAllowed;
10
10
  exports.sessionExpired = sessionExpired;
11
+ exports.sessionInvalidated = sessionInvalidated;
11
12
  exports.serverError = serverError;
12
13
  class OAuthRequestError extends Error {
13
14
  constructor(status, type, message) {
@@ -39,7 +40,10 @@ function forestIdentityNotAllowed(message) {
39
40
  function sessionExpired(message) {
40
41
  return new OAuthRequestError(401, 'session_expired', message);
41
42
  }
43
+ function sessionInvalidated(message) {
44
+ return new OAuthRequestError(401, 'session_invalidated', message);
45
+ }
42
46
  function serverError(message) {
43
47
  return new OAuthRequestError(502, 'server_error', message);
44
48
  }
45
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2F1dGgtZXJyb3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvb2F1dGgvb2F1dGgtZXJyb3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBaUJBLGtDQUVDO0FBRUQsd0NBRUM7QUFFRCxzQ0FFQztBQUVELG9DQUVDO0FBRUQsb0RBRUM7QUFFRCw0REFFQztBQUVELHdDQUVDO0FBRUQsa0NBRUM7QUEvQ0QsTUFBYSxpQkFBa0IsU0FBUSxLQUFLO0lBSTFDLFlBQVksTUFBYyxFQUFFLElBQVksRUFBRSxPQUFlO1FBQ3ZELEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNmLElBQUksQ0FBQyxJQUFJLEdBQUcsbUJBQW1CLENBQUM7UUFDaEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7SUFDbkIsQ0FBQztDQUNGO0FBVkQsOENBVUM7QUFPRCxTQUFnQixXQUFXLENBQUMsS0FBd0I7SUFDbEQsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLGlCQUFpQixFQUFFLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztBQUNqRSxDQUFDO0FBRUQsU0FBZ0IsY0FBYyxDQUFDLE9BQWU7SUFDNUMsT0FBTyxJQUFJLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxpQkFBaUIsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUNoRSxDQUFDO0FBRUQsU0FBZ0IsYUFBYSxDQUFDLE9BQWU7SUFDM0MsT0FBTyxJQUFJLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxnQkFBZ0IsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUMvRCxDQUFDO0FBRUQsU0FBZ0IsWUFBWSxDQUFDLE9BQWU7SUFDMUMsT0FBTyxJQUFJLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxlQUFlLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDOUQsQ0FBQztBQUVELFNBQWdCLG9CQUFvQixDQUFDLE9BQWU7SUFDbEQsT0FBTyxJQUFJLGlCQUFpQixDQUFDLEdBQUcsRUFBRSx3QkFBd0IsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUN2RSxDQUFDO0FBRUQsU0FBZ0Isd0JBQXdCLENBQUMsT0FBZTtJQUN0RCxPQUFPLElBQUksaUJBQWlCLENBQUMsR0FBRyxFQUFFLDZCQUE2QixFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQzVFLENBQUM7QUFFRCxTQUFnQixjQUFjLENBQUMsT0FBZTtJQUM1QyxPQUFPLElBQUksaUJBQWlCLENBQUMsR0FBRyxFQUFFLGlCQUFpQixFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ2hFLENBQUM7QUFFRCxTQUFnQixXQUFXLENBQUMsT0FBZTtJQUN6QyxPQUFPLElBQUksaUJBQWlCLENBQUMsR0FBRyxFQUFFLGNBQWMsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUM3RCxDQUFDIn0=
49
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2F1dGgtZXJyb3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvb2F1dGgvb2F1dGgtZXJyb3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBaUJBLGtDQUVDO0FBRUQsd0NBRUM7QUFFRCxzQ0FFQztBQUVELG9DQUVDO0FBRUQsb0RBRUM7QUFFRCw0REFFQztBQUVELHdDQUVDO0FBRUQsZ0RBRUM7QUFFRCxrQ0FFQztBQW5ERCxNQUFhLGlCQUFrQixTQUFRLEtBQUs7SUFJMUMsWUFBWSxNQUFjLEVBQUUsSUFBWSxFQUFFLE9BQWU7UUFDdkQsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2YsSUFBSSxDQUFDLElBQUksR0FBRyxtQkFBbUIsQ0FBQztRQUNoQyxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztJQUNuQixDQUFDO0NBQ0Y7QUFWRCw4Q0FVQztBQU9ELFNBQWdCLFdBQVcsQ0FBQyxLQUF3QjtJQUNsRCxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQ2pFLENBQUM7QUFFRCxTQUFnQixjQUFjLENBQUMsT0FBZTtJQUM1QyxPQUFPLElBQUksaUJBQWlCLENBQUMsR0FBRyxFQUFFLGlCQUFpQixFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ2hFLENBQUM7QUFFRCxTQUFnQixhQUFhLENBQUMsT0FBZTtJQUMzQyxPQUFPLElBQUksaUJBQWlCLENBQUMsR0FBRyxFQUFFLGdCQUFnQixFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQy9ELENBQUM7QUFFRCxTQUFnQixZQUFZLENBQUMsT0FBZTtJQUMxQyxPQUFPLElBQUksaUJBQWlCLENBQUMsR0FBRyxFQUFFLGVBQWUsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUM5RCxDQUFDO0FBRUQsU0FBZ0Isb0JBQW9CLENBQUMsT0FBZTtJQUNsRCxPQUFPLElBQUksaUJBQWlCLENBQUMsR0FBRyxFQUFFLHdCQUF3QixFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ3ZFLENBQUM7QUFFRCxTQUFnQix3QkFBd0IsQ0FBQyxPQUFlO0lBQ3RELE9BQU8sSUFBSSxpQkFBaUIsQ0FBQyxHQUFHLEVBQUUsNkJBQTZCLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDNUUsQ0FBQztBQUVELFNBQWdCLGNBQWMsQ0FBQyxPQUFlO0lBQzVDLE9BQU8sSUFBSSxpQkFBaUIsQ0FBQyxHQUFHLEVBQUUsaUJBQWlCLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDaEUsQ0FBQztBQUVELFNBQWdCLGtCQUFrQixDQUFDLE9BQWU7SUFDaEQsT0FBTyxJQUFJLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxxQkFBcUIsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUNwRSxDQUFDO0FBRUQsU0FBZ0IsV0FBVyxDQUFDLE9BQWU7SUFDekMsT0FBTyxJQUFJLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxjQUFjLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDN0QsQ0FBQyJ9
@@ -1,9 +1,18 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.default = createOAuthRoutes;
7
+ const crypto_1 = __importDefault(require("crypto"));
8
+ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
4
9
  const bff_token_1 = require("./bff-token");
5
10
  const forest_server_client_1 = require("./forest-server-client");
6
11
  const oauth_error_1 = require("./oauth-error");
12
+ const session_lifecycle_1 = __importDefault(require("./session-lifecycle"));
13
+ function hashPresentedToken(token) {
14
+ return crypto_1.default.createHash('sha256').update(token).digest('base64url');
15
+ }
7
16
  const CODE_VERIFIER_PATTERN = /^[A-Za-z0-9\-._~]{43,128}$/;
8
17
  const S256_CODE_CHALLENGE_PATTERN = /^[A-Za-z0-9_-]{43}$/;
9
18
  const SAFE_EXCHANGE_ERRORS = new Set([
@@ -123,15 +132,15 @@ function computeExpiresIn(serverTokens) {
123
132
  }
124
133
  return Math.min(bff_token_1.BFF_ACCESS_TOKEN_MAX_EXPIRES_IN, saasRemaining);
125
134
  }
126
- async function parseTokenRequest(ctx, options) {
135
+ function parseBody(ctx) {
127
136
  const { body } = ctx.request;
128
137
  if (typeof body !== 'object' || body === null) {
129
138
  throw (0, oauth_error_1.invalidRequest)('Missing request body');
130
139
  }
131
- const params = body;
132
- if (params.grant_type !== 'authorization_code') {
133
- throw (0, oauth_error_1.unsupportedGrantType)('Only authorization_code is supported');
134
- }
140
+ return body;
141
+ }
142
+ async function parseTokenRequest(ctx, options) {
143
+ const params = parseBody(ctx);
135
144
  const request = {
136
145
  code: requireBodyString(params, 'code'),
137
146
  clientId: requireBodyString(params, 'client_id'),
@@ -161,18 +170,27 @@ async function exchangeForServerTokens(request, options) {
161
170
  function isRetriableExchangeError(error) {
162
171
  return !(error instanceof oauth_error_1.OAuthRequestError) || error.status >= 500;
163
172
  }
164
- async function resolveIdentity(serverTokens, options) {
173
+ async function resolveIdentity(renderingId, saasAccessToken, options) {
165
174
  try {
166
- return await options.serverClient.getUserInfo(serverTokens.renderingId, serverTokens.saasAccessToken);
175
+ return await options.serverClient.getUserInfo(renderingId, saasAccessToken);
167
176
  }
168
177
  catch (error) {
169
- options.logger('Warn', 'Failed to resolve user info after exchange', {
170
- renderingId: serverTokens.renderingId,
171
- });
178
+ options.logger('Warn', 'Failed to resolve user info after exchange', { renderingId });
172
179
  throw mapIdentityError(error);
173
180
  }
174
181
  }
175
- async function handleToken(ctx, options) {
182
+ function writeTokenResponse(ctx, accessToken, expiresInSeconds, refreshToken) {
183
+ ctx.set('Cache-Control', 'no-store');
184
+ ctx.set('Pragma', 'no-cache');
185
+ ctx.status = 200;
186
+ ctx.body = {
187
+ access_token: accessToken,
188
+ token_type: 'Bearer',
189
+ expires_in: expiresInSeconds,
190
+ refresh_token: refreshToken,
191
+ };
192
+ }
193
+ async function handleAuthorizationCodeGrant(ctx, options) {
176
194
  const request = await parseTokenRequest(ctx, options);
177
195
  if (!options.sessionStore.claimAuthorizationCode(request.code)) {
178
196
  throw (0, oauth_error_1.invalidGrant)('Authorization code has already been used');
@@ -188,7 +206,7 @@ async function handleToken(ctx, options) {
188
206
  throw error;
189
207
  }
190
208
  const expiresInSeconds = computeExpiresIn(serverTokens);
191
- const user = await resolveIdentity(serverTokens, options);
209
+ const user = await resolveIdentity(serverTokens.renderingId, serverTokens.saasAccessToken, options);
192
210
  const { sid, refreshToken } = options.sessionStore.create({
193
211
  saasAccessToken: serverTokens.saasAccessToken,
194
212
  saasRefreshToken: serverTokens.saasRefreshToken,
@@ -206,15 +224,91 @@ async function handleToken(ctx, options) {
206
224
  renderingId: serverTokens.renderingId,
207
225
  userId: user.id,
208
226
  });
209
- ctx.set('Cache-Control', 'no-store');
210
- ctx.set('Pragma', 'no-cache');
211
- ctx.status = 200;
212
- ctx.body = {
213
- access_token: accessToken,
214
- token_type: 'Bearer',
215
- expires_in: expiresInSeconds,
216
- refresh_token: refreshToken,
217
- };
227
+ writeTokenResponse(ctx, accessToken, expiresInSeconds, refreshToken);
228
+ }
229
+ function expiresInFromAccessToken(saasAccessToken) {
230
+ const decoded = jsonwebtoken_1.default.decode(saasAccessToken);
231
+ if (typeof decoded?.exp !== 'number' || !Number.isFinite(decoded.exp)) {
232
+ return bff_token_1.BFF_ACCESS_TOKEN_MAX_EXPIRES_IN;
233
+ }
234
+ const saasRemaining = decoded.exp - Math.floor(Date.now() / 1000);
235
+ if (saasRemaining <= 0) {
236
+ throw (0, oauth_error_1.sessionExpired)('The Forest server access token is already expired');
237
+ }
238
+ return Math.min(bff_token_1.BFF_ACCESS_TOKEN_MAX_EXPIRES_IN, saasRemaining);
239
+ }
240
+ async function issueAccessForSession(sid, renderingId, refreshToken, options) {
241
+ const saasAccessToken = await (0, session_lifecycle_1.default)({
242
+ sid,
243
+ store: options.sessionStore,
244
+ serverClient: options.serverClient,
245
+ });
246
+ const expiresInSeconds = expiresInFromAccessToken(saasAccessToken);
247
+ const user = await resolveIdentity(renderingId, saasAccessToken, options);
248
+ const accessToken = (0, bff_token_1.issueBffAccessToken)({
249
+ sid,
250
+ user,
251
+ renderingId,
252
+ authSecret: options.authSecret,
253
+ expiresInSeconds,
254
+ });
255
+ return { sid, accessToken, expiresInSeconds, newRefreshToken: refreshToken };
256
+ }
257
+ async function reissueThenCommitRotation(presentedToken, sid, renderingId, newRefreshToken, options) {
258
+ const result = await issueAccessForSession(sid, renderingId, newRefreshToken, options);
259
+ if (!options.sessionStore.commitRotation(presentedToken, newRefreshToken)) {
260
+ throw (0, oauth_error_1.sessionExpired)('Session expired during refresh');
261
+ }
262
+ return result;
263
+ }
264
+ async function handleRefreshGrant(ctx, options) {
265
+ const params = parseBody(ctx);
266
+ const presentedToken = requireBodyString(params, 'refresh_token');
267
+ const presentedHash = hashPresentedToken(presentedToken);
268
+ const inFlight = options.inFlightRefreshByPresentedHash;
269
+ let pending = inFlight.get(presentedHash);
270
+ if (!pending) {
271
+ const rotation = options.sessionStore.prepareRotation(presentedToken);
272
+ if (rotation.outcome === 'reuse') {
273
+ options.sessionStore.destroy(rotation.sid);
274
+ options.logger('Warn', 'Rotated-out refresh token replayed; session invalidated', {
275
+ sid: rotation.sid,
276
+ });
277
+ throw (0, oauth_error_1.sessionInvalidated)('Refresh token was already used; the session is invalidated');
278
+ }
279
+ if (rotation.outcome === 'unknown') {
280
+ throw (0, oauth_error_1.invalidGrant)('Unknown or malformed refresh token');
281
+ }
282
+ if (rotation.outcome === 'replay') {
283
+ options.logger('Info', 'Replayed the last issued pair for a benign retry', {
284
+ sid: rotation.sid,
285
+ });
286
+ pending = issueAccessForSession(rotation.sid, rotation.renderingId, rotation.lastIssuedRefreshToken, options).finally(() => {
287
+ inFlight.delete(presentedHash);
288
+ });
289
+ }
290
+ else {
291
+ pending = reissueThenCommitRotation(presentedToken, rotation.sid, rotation.renderingId, rotation.newRefreshToken, options).finally(() => {
292
+ inFlight.delete(presentedHash);
293
+ });
294
+ }
295
+ inFlight.set(presentedHash, pending);
296
+ }
297
+ const result = await pending;
298
+ options.logger('Info', 'Refreshed BFF session token', { sid: result.sid });
299
+ writeTokenResponse(ctx, result.accessToken, result.expiresInSeconds, result.newRefreshToken);
300
+ }
301
+ async function handleToken(ctx, options) {
302
+ const params = parseBody(ctx);
303
+ if (params.grant_type === 'refresh_token') {
304
+ await handleRefreshGrant(ctx, options);
305
+ return;
306
+ }
307
+ if (params.grant_type === 'authorization_code') {
308
+ await handleAuthorizationCodeGrant(ctx, options);
309
+ return;
310
+ }
311
+ throw (0, oauth_error_1.unsupportedGrantType)('Only authorization_code and refresh_token are supported');
218
312
  }
219
313
  function matchRoute(ctx) {
220
314
  if (ctx.method === 'GET' && ctx.path === '/oauth/authorize')
@@ -237,6 +331,10 @@ function writeError(ctx, error, options) {
237
331
  ctx.body = { error: 'server_error', error_description: 'OAuth processing failed' };
238
332
  }
239
333
  function createOAuthRoutes(options) {
334
+ const runtimeOptions = {
335
+ ...options,
336
+ inFlightRefreshByPresentedHash: new Map(),
337
+ };
240
338
  return async function oauthRoutes(ctx, next) {
241
339
  const handler = matchRoute(ctx);
242
340
  if (!handler) {
@@ -244,11 +342,11 @@ function createOAuthRoutes(options) {
244
342
  return;
245
343
  }
246
344
  try {
247
- await handler(ctx, options);
345
+ await handler(ctx, runtimeOptions);
248
346
  }
249
347
  catch (error) {
250
- writeError(ctx, error, options);
348
+ writeError(ctx, error, runtimeOptions);
251
349
  }
252
350
  };
253
351
  }
254
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2F1dGgtcm91dGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL29hdXRoL29hdXRoLXJvdXRlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWdXQSxvQ0FnQkM7QUF6V0QsMkNBQW1GO0FBQ25GLGlFQUE0RDtBQUM1RCwrQ0FRdUI7QUFXdkIsTUFBTSxxQkFBcUIsR0FBRyw0QkFBNEIsQ0FBQztBQUMzRCxNQUFNLDJCQUEyQixHQUFHLHFCQUFxQixDQUFDO0FBRTFELE1BQU0sb0JBQW9CLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDbkMsaUJBQWlCO0lBQ2pCLGdCQUFnQjtJQUNoQixlQUFlO0lBQ2YscUJBQXFCO0lBQ3JCLHdCQUF3QjtJQUN4QixlQUFlO0NBQ2hCLENBQUMsQ0FBQztBQUVILFNBQVMsYUFBYSxDQUFDLEdBQVksRUFBRSxHQUFXO0lBQzlDLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFN0IsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDekIsTUFBTSxJQUFBLDRCQUFjLEVBQUMsdUNBQXVDLEdBQUcsRUFBRSxDQUFDLENBQUM7SUFDckUsQ0FBQztJQUVELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUVELFNBQVMsaUJBQWlCLENBQUMsSUFBNkIsRUFBRSxHQUFXO0lBQ25FLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUV4QixJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxLQUFLLEtBQUssRUFBRSxFQUFFLENBQUM7UUFDOUMsTUFBTSxJQUFBLDRCQUFjLEVBQUMsK0JBQStCLEdBQUcsRUFBRSxDQUFDLENBQUM7SUFDN0QsQ0FBQztJQUVELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUVELFNBQVMsdUJBQXVCLENBQUMsWUFBb0I7SUFDbkQsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1FBQzlDLE1BQU0sSUFBQSw0QkFBYyxFQUFDLDRCQUE0QixDQUFDLENBQUM7SUFDckQsQ0FBQztBQUNILENBQUM7QUFFRCxTQUFTLDJCQUEyQixDQUNsQyxZQUFrQyxFQUNsQyxXQUFtQixFQUNuQixVQUFrRDtJQUVsRCxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsSUFBSSxZQUFZLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQzlELE1BQU0sSUFBQSw0QkFBYyxFQUFDLHVDQUF1QyxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUVELElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7UUFDeEMsTUFBTSxVQUFVLENBQUMsbURBQW1ELENBQUMsQ0FBQztJQUN4RSxDQUFDO0FBQ0gsQ0FBQztBQUVELFNBQVMsbUJBQW1CLENBQUMsU0FBaUI7SUFDNUMsSUFBSSxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztRQUN4QyxPQUFPLElBQUksK0JBQWlCLENBQUMsR0FBRyxFQUFFLFNBQVMsRUFBRSxvQ0FBb0MsQ0FBQyxDQUFDO0lBQ3JGLENBQUM7SUFFRCxPQUFPLElBQUksK0JBQWlCLENBQzFCLEdBQUcsRUFDSCxjQUFjLEVBQ2QsK0NBQStDLENBQ2hELENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUyxnQkFBZ0IsQ0FBQyxLQUFjO0lBQ3RDLE1BQU0sSUFBSSxHQUFHLEtBQUssWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUV0RCxJQUFJLElBQUksS0FBSyxnQkFBZ0IsRUFBRSxDQUFDO1FBQzlCLE9BQU8sSUFBQSxzQ0FBd0IsRUFBQyxpREFBaUQsQ0FBQyxDQUFDO0lBQ3JGLENBQUM7SUFFRCxPQUFPLElBQUksK0JBQWlCLENBQUMsR0FBRyxFQUFFLDRCQUE0QixFQUFFLDRCQUE0QixDQUFDLENBQUM7QUFDaEcsQ0FBQztBQUVELFNBQVMsc0JBQXNCLENBQzdCLEdBQVksRUFDWixXQUFtQixFQUNuQixLQUF5QixFQUN6QixLQUF3QjtJQUV4QixNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNwQyxNQUFNLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdDLE1BQU0sQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLG1CQUFtQixFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM1RCxJQUFJLEtBQUssS0FBSyxTQUFTLElBQUksS0FBSyxLQUFLLEVBQUU7UUFBRSxNQUFNLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFFakYsR0FBRyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztBQUNsQyxDQUFDO0FBRUQsS0FBSyxVQUFVLGVBQWUsQ0FBQyxHQUFZLEVBQUUsT0FBMkI7SUFDdEUsNkVBQTZFO0lBQzdFLDZFQUE2RTtJQUM3RSxNQUFNLFFBQVEsR0FBRyxhQUFhLENBQUMsR0FBRyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBRWpELElBQUksUUFBUSxLQUFLLFNBQVMsSUFBSSxRQUFRLEtBQUssRUFBRSxFQUFFLENBQUM7UUFDOUMsTUFBTSxJQUFBLDRCQUFjLEVBQUMsdUNBQXVDLENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBRUQsTUFBTSxXQUFXLEdBQUcsYUFBYSxDQUFDLEdBQUcsRUFBRSxjQUFjLENBQUMsQ0FBQztJQUV2RCxJQUFJLFdBQVcsS0FBSyxTQUFTLElBQUksV0FBVyxLQUFLLEVBQUUsRUFBRSxDQUFDO1FBQ3BELE1BQU0sSUFBQSw0QkFBYyxFQUFDLDBDQUEwQyxDQUFDLENBQUM7SUFDbkUsQ0FBQztJQUVELE1BQU0sTUFBTSxHQUFHLE1BQU0sT0FBTyxDQUFDLFlBQVksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUV4RSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDWixNQUFNLElBQUEsNEJBQWMsRUFBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRCwyQkFBMkIsQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFLFdBQVcsRUFBRSw0QkFBYyxDQUFDLENBQUM7SUFFL0UsNEVBQTRFO0lBQzVFLHFEQUFxRDtJQUNyRCxJQUFJLEtBQXlCLENBQUM7SUFFOUIsSUFBSSxDQUFDO1FBQ0gsS0FBSyxHQUFHLGFBQWEsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDcEMsTUFBTSxZQUFZLEdBQUcsYUFBYSxDQUFDLEdBQUcsRUFBRSxlQUFlLENBQUMsQ0FBQztRQUV6RCxJQUFJLFlBQVksS0FBSyxNQUFNLEVBQUUsQ0FBQztZQUM1QixNQUFNLElBQUEsNEJBQWMsRUFBQyw4QkFBOEIsQ0FBQyxDQUFDO1FBQ3ZELENBQUM7UUFFRCxJQUFJLGFBQWEsQ0FBQyxHQUFHLEVBQUUsdUJBQXVCLENBQUMsS0FBSyxNQUFNLEVBQUUsQ0FBQztZQUMzRCxNQUFNLElBQUEsNEJBQWMsRUFBQyxvQ0FBb0MsQ0FBQyxDQUFDO1FBQzdELENBQUM7UUFFRCxNQUFNLGFBQWEsR0FBRyxhQUFhLENBQUMsR0FBRyxFQUFFLGdCQUFnQixDQUFDLENBQUM7UUFFM0QsSUFBSSxhQUFhLEtBQUssU0FBUyxJQUFJLENBQUMsMkJBQTJCLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUM7WUFDcEYsTUFBTSxJQUFBLDRCQUFjLEVBQUMsd0NBQXdDLENBQUMsQ0FBQztRQUNqRSxDQUFDO1FBRUQsSUFBSSxLQUFLLEtBQUssU0FBUyxJQUFJLEtBQUssS0FBSyxFQUFFLEVBQUUsQ0FBQztZQUN4QyxNQUFNLElBQUEsNEJBQWMsRUFBQyxtQ0FBbUMsQ0FBQyxDQUFDO1FBQzVELENBQUM7UUFFRCxNQUFNLE9BQU8sR0FBRyxJQUFJLEdBQUcsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDOUMsTUFBTSxZQUFZLEdBQUcsSUFBSSxHQUFHLENBQUMsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLGtCQUFrQixFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ2hHLFlBQVksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNyRCxZQUFZLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDM0QsWUFBWSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsZUFBZSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3ZELFlBQVksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLGdCQUFnQixFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBQy9ELFlBQVksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLHVCQUF1QixFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQy9ELFlBQVksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztRQUM5QyxZQUFZLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxlQUFlLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDO1FBRTlFLEdBQUcsQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixJQUFJLEtBQUssWUFBWSwrQkFBaUIsRUFBRSxDQUFDO1lBQ3ZDLHNCQUFzQixDQUFDLEdBQUcsRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRXZELE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxLQUFLLENBQUM7SUFDZCxDQUFDO0FBQ0gsQ0FBQztBQUVELFNBQVMsZ0JBQWdCLENBQUMsWUFBMEI7SUFDbEQsTUFBTSxhQUFhLEdBQUcsWUFBWSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztJQUU3RSxJQUFJLGFBQWEsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUN2QixNQUFNLElBQUEsMEJBQVksRUFBQyxtREFBbUQsQ0FBQyxDQUFDO0lBQzFFLENBQUM7SUFFRCxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsMkNBQStCLEVBQUUsYUFBYSxDQUFDLENBQUM7QUFDbEUsQ0FBQztBQVNELEtBQUssVUFBVSxpQkFBaUIsQ0FBQyxHQUFZLEVBQUUsT0FBMkI7SUFDeEUsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLEdBQUcsQ0FBQyxPQUE2QixDQUFDO0lBRW5ELElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxJQUFJLElBQUksS0FBSyxJQUFJLEVBQUUsQ0FBQztRQUM5QyxNQUFNLElBQUEsNEJBQWMsRUFBQyxzQkFBc0IsQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFFRCxNQUFNLE1BQU0sR0FBRyxJQUErQixDQUFDO0lBRS9DLElBQUksTUFBTSxDQUFDLFVBQVUsS0FBSyxvQkFBb0IsRUFBRSxDQUFDO1FBQy9DLE1BQU0sSUFBQSxrQ0FBb0IsRUFBQyxzQ0FBc0MsQ0FBQyxDQUFDO0lBQ3JFLENBQUM7SUFFRCxNQUFNLE9BQU8sR0FBaUI7UUFDNUIsSUFBSSxFQUFFLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUM7UUFDdkMsUUFBUSxFQUFFLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxXQUFXLENBQUM7UUFDaEQsWUFBWSxFQUFFLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxlQUFlLENBQUM7UUFDeEQsV0FBVyxFQUFFLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxjQUFjLENBQUM7S0FDdkQsQ0FBQztJQUVGLHVCQUF1QixDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUU5QyxNQUFNLE1BQU0sR0FBRyxNQUFNLE9BQU8sQ0FBQyxZQUFZLENBQUMsbUJBQW1CLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRWhGLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNaLE1BQU0sSUFBQSwyQkFBYSxFQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUVELDJCQUEyQixDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUUsT0FBTyxDQUFDLFdBQVcsRUFBRSwwQkFBWSxDQUFDLENBQUM7SUFFckYsT0FBTyxPQUFPLENBQUM7QUFDakIsQ0FBQztBQUVELEtBQUssVUFBVSx1QkFBdUIsQ0FDcEMsT0FBcUIsRUFDckIsT0FBMkI7SUFFM0IsSUFBSSxDQUFDO1FBQ0gsT0FBTyxNQUFNLE9BQU8sQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzFELENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2YsSUFBSSxLQUFLLFlBQVkseUNBQWtCLEVBQUUsQ0FBQztZQUN4QyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxzQ0FBc0MsRUFBRSxFQUFFLFNBQVMsRUFBRSxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUMzRixNQUFNLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN6QyxDQUFDO1FBRUQsTUFBTSxLQUFLLENBQUM7SUFDZCxDQUFDO0FBQ0gsQ0FBQztBQUVELFNBQVMsd0JBQXdCLENBQUMsS0FBYztJQUM5QyxPQUFPLENBQUMsQ0FBQyxLQUFLLFlBQVksK0JBQWlCLENBQUMsSUFBSSxLQUFLLENBQUMsTUFBTSxJQUFJLEdBQUcsQ0FBQztBQUN0RSxDQUFDO0FBRUQsS0FBSyxVQUFVLGVBQWUsQ0FDNUIsWUFBMEIsRUFDMUIsT0FBMkI7SUFFM0IsSUFBSSxDQUFDO1FBQ0gsT0FBTyxNQUFNLE9BQU8sQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUMzQyxZQUFZLENBQUMsV0FBVyxFQUN4QixZQUFZLENBQUMsZUFBZSxDQUM3QixDQUFDO0lBQ0osQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSw0Q0FBNEMsRUFBRTtZQUNuRSxXQUFXLEVBQUUsWUFBWSxDQUFDLFdBQVc7U0FDdEMsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoQyxDQUFDO0FBQ0gsQ0FBQztBQUVELEtBQUssVUFBVSxXQUFXLENBQUMsR0FBWSxFQUFFLE9BQTJCO0lBQ2xFLE1BQU0sT0FBTyxHQUFHLE1BQU0saUJBQWlCLENBQUMsR0FBRyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBRXRELElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQy9ELE1BQU0sSUFBQSwwQkFBWSxFQUFDLDBDQUEwQyxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUVELElBQUksWUFBMEIsQ0FBQztJQUUvQixJQUFJLENBQUM7UUFDSCxZQUFZLEdBQUcsTUFBTSx1QkFBdUIsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixJQUFJLHdCQUF3QixDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDcEMsT0FBTyxDQUFDLFlBQVksQ0FBQyx3QkFBd0IsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDOUQsQ0FBQztRQUVELE1BQU0sS0FBSyxDQUFDO0lBQ2QsQ0FBQztJQUVELE1BQU0sZ0JBQWdCLEdBQUcsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDeEQsTUFBTSxJQUFJLEdBQUcsTUFBTSxlQUFlLENBQUMsWUFBWSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBRTFELE1BQU0sRUFBRSxHQUFHLEVBQUUsWUFBWSxFQUFFLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUM7UUFDeEQsZUFBZSxFQUFFLFlBQVksQ0FBQyxlQUFlO1FBQzdDLGdCQUFnQixFQUFFLFlBQVksQ0FBQyxnQkFBZ0I7UUFDL0MsV0FBVyxFQUFFLFlBQVksQ0FBQyxXQUFXO1FBQ3JDLE1BQU0sRUFBRSxJQUFJLENBQUMsRUFBRTtLQUNoQixDQUFDLENBQUM7SUFFSCxNQUFNLFdBQVcsR0FBRyxJQUFBLCtCQUFtQixFQUFDO1FBQ3RDLEdBQUc7UUFDSCxJQUFJO1FBQ0osV0FBVyxFQUFFLFlBQVksQ0FBQyxXQUFXO1FBQ3JDLFVBQVUsRUFBRSxPQUFPLENBQUMsVUFBVTtRQUM5QixnQkFBZ0I7S0FDakIsQ0FBQyxDQUFDO0lBRUgsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsMEJBQTBCLEVBQUU7UUFDakQsV0FBVyxFQUFFLFlBQVksQ0FBQyxXQUFXO1FBQ3JDLE1BQU0sRUFBRSxJQUFJLENBQUMsRUFBRTtLQUNoQixDQUFDLENBQUM7SUFFSCxHQUFHLENBQUMsR0FBRyxDQUFDLGVBQWUsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUNyQyxHQUFHLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUM5QixHQUFHLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQztJQUNqQixHQUFHLENBQUMsSUFBSSxHQUFHO1FBQ1QsWUFBWSxFQUFFLFdBQVc7UUFDekIsVUFBVSxFQUFFLFFBQVE7UUFDcEIsVUFBVSxFQUFFLGdCQUFnQjtRQUM1QixhQUFhLEVBQUUsWUFBWTtLQUM1QixDQUFDO0FBQ0osQ0FBQztBQUlELFNBQVMsVUFBVSxDQUFDLEdBQVk7SUFDOUIsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLEtBQUssSUFBSSxHQUFHLENBQUMsSUFBSSxLQUFLLGtCQUFrQjtRQUFFLE9BQU8sZUFBZSxDQUFDO0lBQ3BGLElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxNQUFNLElBQUksR0FBRyxDQUFDLElBQUksS0FBSyxjQUFjO1FBQUUsT0FBTyxXQUFXLENBQUM7SUFFN0UsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQztBQUVELFNBQVMsVUFBVSxDQUFDLEdBQVksRUFBRSxLQUFjLEVBQUUsT0FBMkI7SUFDM0UsSUFBSSxLQUFLLFlBQVksK0JBQWlCLEVBQUUsQ0FBQztRQUN2QyxHQUFHLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFDMUIsR0FBRyxDQUFDLElBQUksR0FBRyxJQUFBLHlCQUFXLEVBQUMsS0FBSyxDQUFDLENBQUM7UUFFOUIsT0FBTztJQUNULENBQUM7SUFFRCxPQUFPLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxxQkFBcUIsRUFBRTtRQUM3QyxJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUk7UUFDZCxLQUFLLEVBQUUsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsSUFBSSxLQUFLLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztLQUNsRixDQUFDLENBQUM7SUFDSCxHQUFHLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQztJQUNqQixHQUFHLENBQUMsSUFBSSxHQUFHLEVBQUUsS0FBSyxFQUFFLGNBQWMsRUFBRSxpQkFBaUIsRUFBRSx5QkFBeUIsRUFBRSxDQUFDO0FBQ3JGLENBQUM7QUFFRCxTQUF3QixpQkFBaUIsQ0FBQyxPQUEyQjtJQUNuRSxPQUFPLEtBQUssVUFBVSxXQUFXLENBQUMsR0FBRyxFQUFFLElBQUk7UUFDekMsTUFBTSxPQUFPLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRWhDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNiLE1BQU0sSUFBSSxFQUFFLENBQUM7WUFFYixPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksQ0FBQztZQUNILE1BQU0sT0FBTyxDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUM5QixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLFVBQVUsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ2xDLENBQUM7SUFDSCxDQUFDLENBQUM7QUFDSixDQUFDIn0=
352
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2F1dGgtcm91dGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL29hdXRoL29hdXRoLXJvdXRlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQXFnQkEsb0NBcUJDO0FBbmhCRCxvREFBNEI7QUFDNUIsZ0VBQXdDO0FBRXhDLDJDQUFtRjtBQUNuRixpRUFBNEQ7QUFDNUQsK0NBVXVCO0FBQ3ZCLDRFQUEwRDtBQUUxRCxTQUFTLGtCQUFrQixDQUFDLEtBQWE7SUFDdkMsT0FBTyxnQkFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ3ZFLENBQUM7QUFXRCxNQUFNLHFCQUFxQixHQUFHLDRCQUE0QixDQUFDO0FBQzNELE1BQU0sMkJBQTJCLEdBQUcscUJBQXFCLENBQUM7QUFFMUQsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUNuQyxpQkFBaUI7SUFDakIsZ0JBQWdCO0lBQ2hCLGVBQWU7SUFDZixxQkFBcUI7SUFDckIsd0JBQXdCO0lBQ3hCLGVBQWU7Q0FDaEIsQ0FBQyxDQUFDO0FBRUgsU0FBUyxhQUFhLENBQUMsR0FBWSxFQUFFLEdBQVc7SUFDOUMsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUU3QixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN6QixNQUFNLElBQUEsNEJBQWMsRUFBQyx1Q0FBdUMsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUNyRSxDQUFDO0lBRUQsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDO0FBRUQsU0FBUyxpQkFBaUIsQ0FBQyxJQUE2QixFQUFFLEdBQVc7SUFDbkUsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRXhCLElBQUksT0FBTyxLQUFLLEtBQUss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
@@ -17,6 +17,22 @@ export interface CreatedSession {
17
17
  sid: string;
18
18
  refreshToken: string;
19
19
  }
20
+ export type PrepareRotationResult = {
21
+ outcome: 'ready';
22
+ sid: string;
23
+ renderingId: number;
24
+ newRefreshToken: string;
25
+ } | {
26
+ outcome: 'replay';
27
+ sid: string;
28
+ renderingId: number;
29
+ lastIssuedRefreshToken: string;
30
+ } | {
31
+ outcome: 'reuse';
32
+ sid: string;
33
+ } | {
34
+ outcome: 'unknown';
35
+ };
20
36
  export interface UpdateSaasTokensInput {
21
37
  saasAccessToken: string;
22
38
  saasRefreshToken: string;
@@ -26,6 +42,9 @@ export interface SessionStore {
26
42
  get(sid: string): StoredSession | undefined;
27
43
  getSaasRefreshToken(sid: string): string | undefined;
28
44
  updateSaasTokens(sid: string, tokens: UpdateSaasTokensInput): void;
45
+ prepareRotation(presentedToken: string): PrepareRotationResult;
46
+ commitRotation(presentedToken: string, newRefreshToken: string): boolean;
47
+ destroy(sid: string): void;
29
48
  claimAuthorizationCode(code: string): boolean;
30
49
  releaseAuthorizationCode(code: string): void;
31
50
  pendingClaimCount(): number;
@@ -20,6 +20,24 @@ function hashToken(token) {
20
20
  function createInMemorySessionStore({ cipher, now, sessionTtlSeconds, authCodeTtlSeconds = DEFAULT_AUTH_CODE_TTL_SECONDS, maxPendingCodes = DEFAULT_MAX_PENDING_CODES, }) {
21
21
  const sessions = new Map();
22
22
  const usedCodes = new Map();
23
+ const activeRefreshHashToSid = new Map();
24
+ const rotatedRefreshHashToSid = new Map();
25
+ const lastRotationBySid = new Map();
26
+ function forgetRefreshHashes(sid) {
27
+ for (const [hash, owner] of activeRefreshHashToSid) {
28
+ if (owner === sid)
29
+ activeRefreshHashToSid.delete(hash);
30
+ }
31
+ for (const [hash, owner] of rotatedRefreshHashToSid) {
32
+ if (owner === sid)
33
+ rotatedRefreshHashToSid.delete(hash);
34
+ }
35
+ lastRotationBySid.delete(sid);
36
+ }
37
+ function dropSession(sid) {
38
+ sessions.delete(sid);
39
+ forgetRefreshHashes(sid);
40
+ }
23
41
  function purgeExpiredCodes() {
24
42
  const current = now();
25
43
  for (const [code, expiresAt] of usedCodes) {
@@ -31,7 +49,7 @@ function createInMemorySessionStore({ cipher, now, sessionTtlSeconds, authCodeTt
31
49
  const current = now();
32
50
  for (const [sid, session] of sessions) {
33
51
  if (current >= session.expiresAt)
34
- sessions.delete(sid);
52
+ dropSession(sid);
35
53
  }
36
54
  }
37
55
  function liveSession(sid) {
@@ -39,7 +57,7 @@ function createInMemorySessionStore({ cipher, now, sessionTtlSeconds, authCodeTt
39
57
  if (!session)
40
58
  return undefined;
41
59
  if (now() >= session.expiresAt) {
42
- sessions.delete(sid);
60
+ dropSession(sid);
43
61
  return undefined;
44
62
  }
45
63
  return session;
@@ -49,14 +67,16 @@ function createInMemorySessionStore({ cipher, now, sessionTtlSeconds, authCodeTt
49
67
  purgeExpiredSessions();
50
68
  const sid = createSid();
51
69
  const refreshToken = createOpaqueToken();
70
+ const refreshTokenHash = hashToken(refreshToken);
52
71
  sessions.set(sid, {
53
72
  saasAccessToken: input.saasAccessToken,
54
73
  saasRefreshTokenBlob: cipher.encrypt(input.saasRefreshToken),
55
- refreshTokenHash: hashToken(refreshToken),
74
+ refreshTokenHash,
56
75
  renderingId: input.renderingId,
57
76
  userId: input.userId,
58
77
  expiresAt: now() + sessionTtlSeconds * 1000,
59
78
  });
79
+ activeRefreshHashToSid.set(refreshTokenHash, sid);
60
80
  return { sid, refreshToken };
61
81
  },
62
82
  get(sid) {
@@ -74,6 +94,59 @@ function createInMemorySessionStore({ cipher, now, sessionTtlSeconds, authCodeTt
74
94
  session.saasAccessToken = tokens.saasAccessToken;
75
95
  session.saasRefreshTokenBlob = cipher.encrypt(tokens.saasRefreshToken);
76
96
  },
97
+ prepareRotation(presentedToken) {
98
+ const hash = hashToken(presentedToken);
99
+ const reusedSid = rotatedRefreshHashToSid.get(hash);
100
+ if (reusedSid !== undefined) {
101
+ const session = liveSession(reusedSid);
102
+ if (!session)
103
+ return { outcome: 'unknown' };
104
+ const lastRotation = lastRotationBySid.get(reusedSid);
105
+ if (lastRotation?.rotatedHash === hash) {
106
+ return {
107
+ outcome: 'replay',
108
+ sid: reusedSid,
109
+ renderingId: session.renderingId,
110
+ lastIssuedRefreshToken: cipher.decrypt(lastRotation.issuedRefreshBlob),
111
+ };
112
+ }
113
+ return { outcome: 'reuse', sid: reusedSid };
114
+ }
115
+ const sid = activeRefreshHashToSid.get(hash);
116
+ if (sid === undefined)
117
+ return { outcome: 'unknown' };
118
+ const session = liveSession(sid);
119
+ if (!session)
120
+ return { outcome: 'unknown' };
121
+ return {
122
+ outcome: 'ready',
123
+ sid,
124
+ renderingId: session.renderingId,
125
+ newRefreshToken: createOpaqueToken(),
126
+ };
127
+ },
128
+ commitRotation(presentedToken, newRefreshToken) {
129
+ const hash = hashToken(presentedToken);
130
+ const sid = activeRefreshHashToSid.get(hash);
131
+ if (sid === undefined)
132
+ return false;
133
+ const session = liveSession(sid);
134
+ if (!session)
135
+ return false;
136
+ const newHash = hashToken(newRefreshToken);
137
+ activeRefreshHashToSid.delete(hash);
138
+ rotatedRefreshHashToSid.set(hash, sid);
139
+ lastRotationBySid.set(sid, {
140
+ rotatedHash: hash,
141
+ issuedRefreshBlob: cipher.encrypt(newRefreshToken),
142
+ });
143
+ activeRefreshHashToSid.set(newHash, sid);
144
+ session.refreshTokenHash = newHash;
145
+ return true;
146
+ },
147
+ destroy(sid) {
148
+ dropSession(sid);
149
+ },
77
150
  claimAuthorizationCode(code) {
78
151
  purgeExpiredCodes();
79
152
  if (usedCodes.has(code))
@@ -92,4 +165,4 @@ function createInMemorySessionStore({ cipher, now, sessionTtlSeconds, authCodeTt
92
165
  },
93
166
  };
94
167
  }
95
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Vzc2lvbi1zdG9yZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9vYXV0aC9zZXNzaW9uLXN0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBbURBLDhCQUVDO0FBVUQsNkNBa0dDO0FBL0pELG9EQUE0QjtBQThDNUIsTUFBTSw2QkFBNkIsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQzdDLE1BQU0seUJBQXlCLEdBQUcsS0FBTSxDQUFDO0FBRXpDLFNBQWdCLFNBQVM7SUFDdkIsT0FBTyxnQkFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDdEQsQ0FBQztBQUVELFNBQVMsaUJBQWlCO0lBQ3hCLE9BQU8sZ0JBQU0sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ3RELENBQUM7QUFFRCxTQUFTLFNBQVMsQ0FBQyxLQUFhO0lBQzlCLE9BQU8sZ0JBQU0sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUN2RSxDQUFDO0FBRUQsU0FBd0IsMEJBQTBCLENBQUMsRUFDakQsTUFBTSxFQUNOLEdBQUcsRUFDSCxpQkFBaUIsRUFDakIsa0JBQWtCLEdBQUcsNkJBQTZCLEVBQ2xELGVBQWUsR0FBRyx5QkFBeUIsR0FDdkI7SUFDcEIsTUFBTSxRQUFRLEdBQUcsSUFBSSxHQUFHLEVBQXlCLENBQUM7SUFDbEQsTUFBTSxTQUFTLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7SUFFNUMsU0FBUyxpQkFBaUI7UUFDeEIsTUFBTSxPQUFPLEdBQUcsR0FBRyxFQUFFLENBQUM7UUFFdEIsS0FBSyxNQUFNLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxJQUFJLFNBQVMsRUFBRSxDQUFDO1lBQzFDLElBQUksT0FB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
168
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Vzc2lvbi1zdG9yZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9vYXV0aC9zZXNzaW9uLXN0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBNERBLDhCQUVDO0FBVUQsNkNBMExDO0FBaFFELG9EQUE0QjtBQXVENUIsTUFBTSw2QkFBNkIsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQzdDLE1BQU0seUJBQXlCLEdBQUcsS0FBTSxDQUFDO0FBRXpDLFNBQWdCLFNBQVM7SUFDdkIsT0FBTyxnQkFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDdEQsQ0FBQztBQUVELFNBQVMsaUJBQWlCO0lBQ3hCLE9BQU8sZ0JBQU0sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ3RELENBQUM7QUFFRCxTQUFTLFNBQVMsQ0FBQyxLQUFhO0lBQzlCLE9BQU8sZ0JBQU0sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUN2RSxDQUFDO0FBRUQsU0FBd0IsMEJBQTBCLENBQUMsRUFDakQsTUFBTSxFQUNOLEdBQUcsRUFDSCxpQkFBaUIsRUFDakIsa0JBQWtCLEdBQUcsNkJBQTZCLEVBQ2xELGVBQWUsR0FBRyx5QkFBeUIsR0FDdkI7SUFDcEIsTUFBTSxRQUFRLEdBQUcsSUFBSSxHQUFHLEVBQXlCLENBQUM7SUFDbEQsTUFBTSxTQUFTLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7SUFDNUMsTUFBTSxzQkFBc0IsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUN6RCxNQUFNLHVCQUF1QixHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO0lBQzFELE1BQU0saUJBQWlCLEdBQUcsSUFBSSxHQUFHLEVBRzlCLENB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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forestadmin/agent-bff",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "main": "dist/index.js",
5
5
  "bin": {
6
6
  "forest-bff": "dist/cli.js"