Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(@aws-amplify/core): Support clock skew #4844

Merged
merged 13 commits into from
Feb 6, 2020
Merged
6 changes: 5 additions & 1 deletion packages/core/__tests__/Signer-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@ jest.mock('../src/Facet', () => {
};
return { update };
};

return {
AWS: ret,
};
});

import Signer from '../src/Signer';
import AWS from '../src';
import * as Amplify from '../src';

describe('Signer test', () => {
describe('sign test', () => {
Expand All @@ -45,6 +46,8 @@ describe('Signer test', () => {
.spyOn(Date.prototype, 'toISOString')
.mockReturnValueOnce('0');

const getDateSpy = jest.spyOn(Amplify.Date, 'getDateWithClockOffset');

const res = {
headers: {
Authorization:
Expand All @@ -56,6 +59,7 @@ describe('Signer test', () => {
url: url,
};
expect(Signer.sign(request, access_info)).toEqual(res);
expect(getDateSpy).toHaveBeenCalledTimes(1);

spyon.mockClear();
});
Expand Down
7 changes: 5 additions & 2 deletions packages/core/src/Signer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/

import { ConsoleLogger as Logger } from './Logger';
import * as Util from './Util';
import { AWS } from './Facet';

const logger = new Logger('Signer'),
Expand Down Expand Up @@ -299,7 +300,7 @@ export default class Signer {
request.headers = request.headers || {};

// datetime string and date string
const dt = new Date(),
const dt = Util.Date.getDateWithClockOffset(),
dt_str = dt.toISOString().replace(/[:\-]|\.\d{3}/g, ''),
d_str = dt_str.substr(0, 8);

Expand Down Expand Up @@ -370,7 +371,9 @@ export default class Signer {
const body: any =
typeof urlOrRequest === 'object' ? urlOrRequest.body : undefined;

const now = new Date().toISOString().replace(/[:\-]|\.\d{3}/g, '');
const now = Util.Date.getDateWithClockOffset()
.toISOString()
.replace(/[:\-]|\.\d{3}/g, '');
const today = now.substr(0, 8);
// Intentionally discarding search
const { search, ...parsedUrl } = url.parse(urlToSign, true, true);
Expand Down
38 changes: 38 additions & 0 deletions packages/core/src/Util/Date.test.ts
Original file line number Diff line number Diff line change
@@ -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)
);
});
});
});
28 changes: 28 additions & 0 deletions packages/core/src/Util/Date.ts
Original file line number Diff line number Diff line change
@@ -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,
ericclemmons marked this conversation as resolved.
Show resolved Hide resolved

getDateWithClockOffset() {
ericclemmons marked this conversation as resolved.
Show resolved Hide resolved
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 };
1 change: 1 addition & 0 deletions packages/core/src/Util/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './Retry';
export { default as Mutex } from './Mutex';
export { default as Reachability } from './Reachability';
export * from './Date';