From 2f8333b6b7501b1ad828f0b2328f09e92fca13f9 Mon Sep 17 00:00:00 2001 From: Thiago Hirata Date: Thu, 24 Oct 2019 16:15:47 -0300 Subject: [PATCH 01/11] fix(@aws-amplify/core): AWS.config.systemClockOffset for signing requests --- packages/core/__tests__/Signer-test.ts | 9 +++++++-- packages/core/src/Signer.ts | 7 +++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/core/__tests__/Signer-test.ts b/packages/core/__tests__/Signer-test.ts index b3991353fa4..5531dc40b02 100644 --- a/packages/core/__tests__/Signer-test.ts +++ b/packages/core/__tests__/Signer-test.ts @@ -1,5 +1,5 @@ jest.mock('../src/Facet', () => { - let ret = { util: { crypto: { lib: {} } } }; + let ret = { util: { crypto: { lib: {} }, date: {} } }; ret['util']['crypto']['lib']['createHmac'] = () => { const update = () => { return { @@ -20,13 +20,15 @@ jest.mock('../src/Facet', () => { }; return { update }; }; + ret['util']['date']['getDate'] = () => new Date(); + return { AWS: ret, }; }); import Signer from '../src/Signer'; -import AWS from '../src'; +import { AWS } from '../src/Facet'; describe('Signer test', () => { describe('sign test', () => { @@ -45,6 +47,8 @@ describe('Signer test', () => { .spyOn(Date.prototype, 'toISOString') .mockReturnValueOnce('0'); + const getDateSpy = jest.spyOn(AWS['util']['date'], 'getDate'); + const res = { headers: { Authorization: @@ -56,6 +60,7 @@ describe('Signer test', () => { url: url, }; expect(Signer.sign(request, access_info)).toEqual(res); + expect(getDateSpy).toHaveBeenCalledTimes(1); spyon.mockClear(); }); diff --git a/packages/core/src/Signer.ts b/packages/core/src/Signer.ts index 751dc4e15a4..3fbd15530e0 100644 --- a/packages/core/src/Signer.ts +++ b/packages/core/src/Signer.ts @@ -299,7 +299,7 @@ export default class Signer { request.headers = request.headers || {}; // datetime string and date string - const dt = new Date(), + const dt = AWS['util']['date'].getDate(), dt_str = dt.toISOString().replace(/[:\-]|\.\d{3}/g, ''), d_str = dt_str.substr(0, 8); @@ -370,7 +370,10 @@ export default class Signer { const body: any = typeof urlOrRequest === 'object' ? urlOrRequest.body : undefined; - const now = new Date().toISOString().replace(/[:\-]|\.\d{3}/g, ''); + const now = AWS['util']['date'] + .getDate() + .toISOString() + .replace(/[:\-]|\.\d{3}/g, ''); const today = now.substr(0, 8); // Intentionally discarding search const { search, ...parsedUrl } = url.parse(urlToSign, true, true); From 73554455158b8b0a9a2be32a78770805e060bd9c Mon Sep 17 00:00:00 2001 From: Eric Clemmons Date: Tue, 4 Feb 2020 16:37:49 -0800 Subject: [PATCH 02/11] Add Util/Date to support new Date() with clock offset --- packages/core/src/Util/Date.ts | 28 ++++++++++++++++++++++++++++ packages/core/src/Util/index.ts | 1 + 2 files changed, 29 insertions(+) create mode 100644 packages/core/src/Util/Date.ts diff --git a/packages/core/src/Util/Date.ts b/packages/core/src/Util/Date.ts new file mode 100644 index 00000000000..7af00e702c7 --- /dev/null +++ b/packages/core/src/Util/Date.ts @@ -0,0 +1,28 @@ +/** + * Date & time utility functions to abstract the `aws-sdk` away from users. + * (v2 => v3 modularization is a breaking change) + * + * @see https://github.com/aws/aws-sdk-js/blob/6edf586dcc1de7fe8fbfbbd9a0d2b1847921e6e1/lib/util.js#L262 + */ + +const DateUtils = { + clockOffset: 0, + + getDateWithClockOffset() { + if (DateUtils.clockOffset) { + return new Date(new Date().getTime() + DateUtils.clockOffset); + } else { + return new Date(); + } + }, + + getClockOffset() { + return DateUtils.clockOffset; + }, + + setClockOffset(offset: null | number) { + DateUtils.clockOffset = offset; + }, +}; + +export { DateUtils as Date }; diff --git a/packages/core/src/Util/index.ts b/packages/core/src/Util/index.ts index 0e032f729f4..6ef3123a2d2 100644 --- a/packages/core/src/Util/index.ts +++ b/packages/core/src/Util/index.ts @@ -1,3 +1,4 @@ export * from './Retry'; export { default as Mutex } from './Mutex'; export { default as Reachability } from './Reachability'; +export * from './Date'; From aaead64082ecb81119fa4dbd4a5eb189d7660abb Mon Sep 17 00:00:00 2001 From: Eric Clemmons Date: Tue, 4 Feb 2020 16:38:08 -0800 Subject: [PATCH 03/11] Add tests for Utils.Date --- packages/core/src/Util/Date.test.ts | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 packages/core/src/Util/Date.test.ts diff --git a/packages/core/src/Util/Date.test.ts b/packages/core/src/Util/Date.test.ts new file mode 100644 index 00000000000..d5a4c607d4a --- /dev/null +++ b/packages/core/src/Util/Date.test.ts @@ -0,0 +1,38 @@ +import { Date as DateUtils } from './Date'; + +// Mock Date (https://github.com/facebook/jest/issues/2234#issuecomment-308121037) +const staticDate = new Date('2020-01-01'); +// @ts-ignore Type 'typeof Date' is not assignable to type 'DateConstructor'. +Date = class extends Date { + // @ts-ignore Constructors for derived classes must contain a 'super' call.ts(2377) + constructor() { + return staticDate; + } +}; + +describe('Date', () => { + describe('getDateWithClockOffset()', () => { + it('should return a new Date()', () => { + console.log(new Date()); + expect(DateUtils.getDateWithClockOffset()).toEqual(new Date()); + }); + }); + + describe('getClockOffset()', () => { + it('should default to 0', () => { + expect(DateUtils.getClockOffset()).toEqual(0); + }); + }); + + describe('with setClockOffset()', () => { + beforeAll(() => { + DateUtils.setClockOffset(1000); + }); + + describe('getDate()', () => { + expect(DateUtils.getDateWithClockOffset()).toEqual( + new Date(new Date().getTime() + 1000) + ); + }); + }); +}); From 6453dd284a3f57ffec12d6981dc9d0b9d41b96e2 Mon Sep 17 00:00:00 2001 From: Eric Clemmons Date: Tue, 4 Feb 2020 16:39:15 -0800 Subject: [PATCH 04/11] Signer users Util.Date --- packages/core/__tests__/Signer-test.ts | 5 ++--- packages/core/src/Signer.ts | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/core/__tests__/Signer-test.ts b/packages/core/__tests__/Signer-test.ts index 5531dc40b02..da8cb463751 100644 --- a/packages/core/__tests__/Signer-test.ts +++ b/packages/core/__tests__/Signer-test.ts @@ -20,7 +20,6 @@ jest.mock('../src/Facet', () => { }; return { update }; }; - ret['util']['date']['getDate'] = () => new Date(); return { AWS: ret, @@ -28,7 +27,7 @@ jest.mock('../src/Facet', () => { }); import Signer from '../src/Signer'; -import { AWS } from '../src/Facet'; +import * as Amplify from '../src'; describe('Signer test', () => { describe('sign test', () => { @@ -47,7 +46,7 @@ describe('Signer test', () => { .spyOn(Date.prototype, 'toISOString') .mockReturnValueOnce('0'); - const getDateSpy = jest.spyOn(AWS['util']['date'], 'getDate'); + const getDateSpy = jest.spyOn(Amplify.Date, 'getDateWithClockOffset'); const res = { headers: { diff --git a/packages/core/src/Signer.ts b/packages/core/src/Signer.ts index 3fbd15530e0..faa2dc4a2f6 100644 --- a/packages/core/src/Signer.ts +++ b/packages/core/src/Signer.ts @@ -12,6 +12,7 @@ */ import { ConsoleLogger as Logger } from './Logger'; +import * as Util from './Util'; import { AWS } from './Facet'; const logger = new Logger('Signer'), @@ -299,7 +300,7 @@ export default class Signer { request.headers = request.headers || {}; // datetime string and date string - const dt = AWS['util']['date'].getDate(), + const dt = Util.Date.getDateWithClockOffset(), dt_str = dt.toISOString().replace(/[:\-]|\.\d{3}/g, ''), d_str = dt_str.substr(0, 8); @@ -370,8 +371,7 @@ export default class Signer { const body: any = typeof urlOrRequest === 'object' ? urlOrRequest.body : undefined; - const now = AWS['util']['date'] - .getDate() + const now = Util.Date.getDateWithClockOffset() .toISOString() .replace(/[:\-]|\.\d{3}/g, ''); const today = now.substr(0, 8); From de6ff76b7f9afc3de268b0b42f0a23d12d697825 Mon Sep 17 00:00:00 2001 From: Eric Clemmons Date: Tue, 4 Feb 2020 16:41:39 -0800 Subject: [PATCH 05/11] Remove unused "date" for mocking --- packages/core/__tests__/Signer-test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/__tests__/Signer-test.ts b/packages/core/__tests__/Signer-test.ts index da8cb463751..bd4e1b46b07 100644 --- a/packages/core/__tests__/Signer-test.ts +++ b/packages/core/__tests__/Signer-test.ts @@ -1,5 +1,5 @@ jest.mock('../src/Facet', () => { - let ret = { util: { crypto: { lib: {} }, date: {} } }; + let ret = { util: { crypto: { lib: {} } } }; ret['util']['crypto']['lib']['createHmac'] = () => { const update = () => { return { From 96e7236a46c4b587cc316ac2b5e957ab9ef811ab Mon Sep 17 00:00:00 2001 From: Eric Clemmons Date: Tue, 4 Feb 2020 16:44:26 -0800 Subject: [PATCH 06/11] Rename Date to DateUtils to allow "import { DateUtils }" --- packages/core/__tests__/Signer-test.ts | 5 ++++- packages/core/src/Signer.ts | 4 ++-- packages/core/src/Util/{Date.test.ts => DateUtils.test.ts} | 3 +-- packages/core/src/Util/{Date.ts => DateUtils.ts} | 4 +--- packages/core/src/Util/index.ts | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) rename packages/core/src/Util/{Date.test.ts => DateUtils.test.ts} (92%) rename packages/core/src/Util/{Date.ts => DateUtils.ts} (91%) diff --git a/packages/core/__tests__/Signer-test.ts b/packages/core/__tests__/Signer-test.ts index bd4e1b46b07..764cf8b11e8 100644 --- a/packages/core/__tests__/Signer-test.ts +++ b/packages/core/__tests__/Signer-test.ts @@ -46,7 +46,10 @@ describe('Signer test', () => { .spyOn(Date.prototype, 'toISOString') .mockReturnValueOnce('0'); - const getDateSpy = jest.spyOn(Amplify.Date, 'getDateWithClockOffset'); + const getDateSpy = jest.spyOn( + Amplify.DateUtils, + 'getDateWithClockOffset' + ); const res = { headers: { diff --git a/packages/core/src/Signer.ts b/packages/core/src/Signer.ts index faa2dc4a2f6..3f6fd0d0d3f 100644 --- a/packages/core/src/Signer.ts +++ b/packages/core/src/Signer.ts @@ -300,7 +300,7 @@ export default class Signer { request.headers = request.headers || {}; // datetime string and date string - const dt = Util.Date.getDateWithClockOffset(), + const dt = Util.DateUtils.getDateWithClockOffset(), dt_str = dt.toISOString().replace(/[:\-]|\.\d{3}/g, ''), d_str = dt_str.substr(0, 8); @@ -371,7 +371,7 @@ export default class Signer { const body: any = typeof urlOrRequest === 'object' ? urlOrRequest.body : undefined; - const now = Util.Date.getDateWithClockOffset() + const now = Util.DateUtils.getDateWithClockOffset() .toISOString() .replace(/[:\-]|\.\d{3}/g, ''); const today = now.substr(0, 8); diff --git a/packages/core/src/Util/Date.test.ts b/packages/core/src/Util/DateUtils.test.ts similarity index 92% rename from packages/core/src/Util/Date.test.ts rename to packages/core/src/Util/DateUtils.test.ts index d5a4c607d4a..c1aae65444b 100644 --- a/packages/core/src/Util/Date.test.ts +++ b/packages/core/src/Util/DateUtils.test.ts @@ -1,4 +1,4 @@ -import { Date as DateUtils } from './Date'; +import { DateUtils } from './DateUtils'; // Mock Date (https://github.com/facebook/jest/issues/2234#issuecomment-308121037) const staticDate = new Date('2020-01-01'); @@ -13,7 +13,6 @@ Date = class extends Date { describe('Date', () => { describe('getDateWithClockOffset()', () => { it('should return a new Date()', () => { - console.log(new Date()); expect(DateUtils.getDateWithClockOffset()).toEqual(new Date()); }); }); diff --git a/packages/core/src/Util/Date.ts b/packages/core/src/Util/DateUtils.ts similarity index 91% rename from packages/core/src/Util/Date.ts rename to packages/core/src/Util/DateUtils.ts index 7af00e702c7..c2100b38f9b 100644 --- a/packages/core/src/Util/Date.ts +++ b/packages/core/src/Util/DateUtils.ts @@ -5,7 +5,7 @@ * @see https://github.com/aws/aws-sdk-js/blob/6edf586dcc1de7fe8fbfbbd9a0d2b1847921e6e1/lib/util.js#L262 */ -const DateUtils = { +export const DateUtils = { clockOffset: 0, getDateWithClockOffset() { @@ -24,5 +24,3 @@ const DateUtils = { DateUtils.clockOffset = offset; }, }; - -export { DateUtils as Date }; diff --git a/packages/core/src/Util/index.ts b/packages/core/src/Util/index.ts index 6ef3123a2d2..e22e2984509 100644 --- a/packages/core/src/Util/index.ts +++ b/packages/core/src/Util/index.ts @@ -1,4 +1,4 @@ export * from './Retry'; export { default as Mutex } from './Mutex'; export { default as Reachability } from './Reachability'; -export * from './Date'; +export * from './DateUtils'; From 085273e418ff28994cfd1dba395d960b156c66b8 Mon Sep 17 00:00:00 2001 From: Eric Clemmons Date: Tue, 4 Feb 2020 16:54:55 -0800 Subject: [PATCH 07/11] Reference DateUtils directly vs. Utils.DateUtils --- packages/core/__tests__/Signer-test.ts | 7 ++----- packages/core/src/Signer.ts | 6 +++--- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/core/__tests__/Signer-test.ts b/packages/core/__tests__/Signer-test.ts index 764cf8b11e8..0eb43393aa4 100644 --- a/packages/core/__tests__/Signer-test.ts +++ b/packages/core/__tests__/Signer-test.ts @@ -27,7 +27,7 @@ jest.mock('../src/Facet', () => { }); import Signer from '../src/Signer'; -import * as Amplify from '../src'; +import { DateUtils } from '../src'; describe('Signer test', () => { describe('sign test', () => { @@ -46,10 +46,7 @@ describe('Signer test', () => { .spyOn(Date.prototype, 'toISOString') .mockReturnValueOnce('0'); - const getDateSpy = jest.spyOn( - Amplify.DateUtils, - 'getDateWithClockOffset' - ); + const getDateSpy = jest.spyOn(DateUtils, 'getDateWithClockOffset'); const res = { headers: { diff --git a/packages/core/src/Signer.ts b/packages/core/src/Signer.ts index 3f6fd0d0d3f..66616f66b04 100644 --- a/packages/core/src/Signer.ts +++ b/packages/core/src/Signer.ts @@ -12,7 +12,7 @@ */ import { ConsoleLogger as Logger } from './Logger'; -import * as Util from './Util'; +import { DateUtils } from './Util'; import { AWS } from './Facet'; const logger = new Logger('Signer'), @@ -300,7 +300,7 @@ export default class Signer { request.headers = request.headers || {}; // datetime string and date string - const dt = Util.DateUtils.getDateWithClockOffset(), + const dt = DateUtils.getDateWithClockOffset(), dt_str = dt.toISOString().replace(/[:\-]|\.\d{3}/g, ''), d_str = dt_str.substr(0, 8); @@ -371,7 +371,7 @@ export default class Signer { const body: any = typeof urlOrRequest === 'object' ? urlOrRequest.body : undefined; - const now = Util.DateUtils.getDateWithClockOffset() + const now = DateUtils.getDateWithClockOffset() .toISOString() .replace(/[:\-]|\.\d{3}/g, ''); const today = now.substr(0, 8); From 46ea3a03ce8bd00b03a88af1e2cb2d94e001a45c Mon Sep 17 00:00:00 2001 From: Eric Clemmons Date: Thu, 6 Feb 2020 10:27:27 -0800 Subject: [PATCH 08/11] Move DateUtils.test.ts so that core can build --- .../{src/Util/DateUtils.test.ts => __tests__/DateUtils-test.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/core/{src/Util/DateUtils.test.ts => __tests__/DateUtils-test.ts} (100%) diff --git a/packages/core/src/Util/DateUtils.test.ts b/packages/core/__tests__/DateUtils-test.ts similarity index 100% rename from packages/core/src/Util/DateUtils.test.ts rename to packages/core/__tests__/DateUtils-test.ts From a546192c47ea6dedadcb469b65d225b19ba6c353 Mon Sep 17 00:00:00 2001 From: Eric Clemmons Date: Thu, 6 Feb 2020 10:27:56 -0800 Subject: [PATCH 09/11] Add annotation to clockOffset for documentation & intellisense --- packages/core/src/Util/DateUtils.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/core/src/Util/DateUtils.ts b/packages/core/src/Util/DateUtils.ts index c2100b38f9b..1853b81c15d 100644 --- a/packages/core/src/Util/DateUtils.ts +++ b/packages/core/src/Util/DateUtils.ts @@ -6,6 +6,9 @@ */ export const DateUtils = { + /** + * Milliseconds to offset the date to compensate for clock skew between device & services + */ clockOffset: 0, getDateWithClockOffset() { From 6630330efc85bbeaf95743df352217ce28b63eb7 Mon Sep 17 00:00:00 2001 From: Eric Clemmons Date: Thu, 6 Feb 2020 10:36:54 -0800 Subject: [PATCH 10/11] Fix test path --- packages/core/__tests__/DateUtils-test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/__tests__/DateUtils-test.ts b/packages/core/__tests__/DateUtils-test.ts index c1aae65444b..ff892529d1f 100644 --- a/packages/core/__tests__/DateUtils-test.ts +++ b/packages/core/__tests__/DateUtils-test.ts @@ -1,4 +1,4 @@ -import { DateUtils } from './DateUtils'; +import { DateUtils } from '../src/Util/DateUtils'; // Mock Date (https://github.com/facebook/jest/issues/2234#issuecomment-308121037) const staticDate = new Date('2020-01-01'); From 501ffa50e4d1aa6b1786d5919e9ee4bfc4f508d9 Mon Sep 17 00:00:00 2001 From: Eric Clemmons Date: Thu, 6 Feb 2020 10:37:03 -0800 Subject: [PATCH 11/11] Improve JSDoc --- packages/core/src/Util/DateUtils.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/core/src/Util/DateUtils.ts b/packages/core/src/Util/DateUtils.ts index 1853b81c15d..88dc2c0e1c1 100644 --- a/packages/core/src/Util/DateUtils.ts +++ b/packages/core/src/Util/DateUtils.ts @@ -19,11 +19,17 @@ export const DateUtils = { } }, + /** + * @returns {number} Clock offset in milliseconds + */ getClockOffset() { return DateUtils.clockOffset; }, - setClockOffset(offset: null | number) { + /** + * @param {number} offset Clock offset in milliseconds + */ + setClockOffset(offset: number) { DateUtils.clockOffset = offset; }, };