Compare commits

...

5 Commits

Author SHA1 Message Date
Frédéric Meinnel 6927f2b6ee yay 2024-01-11 17:04:08 +01:00
Frédéric Meinnel f5fc423b0f handle non utc input date 2024-01-11 16:10:15 +01:00
Frédéric Meinnel d8dc674a1a fixing the lifecycle configuration date parsing 2024-01-11 15:32:05 +01:00
Frédéric Meinnel 471c122e99 add content-md5 header to signed headers 2024-01-11 14:53:25 +01:00
Frédéric Meinnel 22b5de96db adding payload to generateV4Headers 2024-01-11 12:18:14 +01:00
4 changed files with 46 additions and 8 deletions

View File

@ -181,7 +181,8 @@ function generateV4Headers(
secretKeyValue: string,
awsService: string,
proxyPath: string,
sessionToken: string
sessionToken: string,
payload: string,
) {
Object.assign(request, { headers: {} });
const amzDate = convertUTCtoISO8601(Date.now());
@ -194,7 +195,7 @@ function generateV4Headers(
const timestamp = amzDate;
const algorithm = 'AWS4-HMAC-SHA256';
let payload = '';
payload = payload || '';
if (request.method === 'POST') {
payload = queryString.stringify(data, undefined, undefined, {
encodeURIComponent,
@ -205,7 +206,8 @@ function generateV4Headers(
request.setHeader('host', request._headers.host);
request.setHeader('x-amz-date', amzDate);
request.setHeader('x-amz-content-sha256', payloadChecksum);
request.setHeader('content-md5', crypto.createHash('md5')
.update(payload, 'binary').digest('base64'))
if (sessionToken) {
request.setHeader('x-amz-security-token', sessionToken);
}
@ -215,6 +217,7 @@ function generateV4Headers(
.filter(headerName =>
headerName.startsWith('x-amz-')
|| headerName.startsWith('x-scal-')
|| headerName === 'content-md5'
|| headerName === 'host'
).sort().join(';');
const params = { request, signedHeaders, payloadChecksum,

View File

@ -501,15 +501,27 @@ export default class LifecycleConfiguration {
_checkDate(date: string) {
const isoRegex = new RegExp('^(-?(?:[1-9][0-9]*)?[0-9]{4})-' +
'(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9])' +
':([0-5][0-9]):([0-5][0-9])(\\.[0-9]+)?(Z)?$');
':([0-5][0-9]):([0-5][0-9])(\\.[0-9]+)?(Z|[+-][0-5][0-9]:[0-5][0-9])?$');
if (!isoRegex.test(date)) {
const msg = 'Date must be in ISO 8601 format';
return errors.InvalidArgument.customizeDescription(msg);
}
const midnightRegex = new RegExp('^(-?(?:[1-9][0-9]*)?[0-9]{4})-' +
'(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T00' +
':00:00(\\.0+)?(Z)?$');
if (!midnightRegex.test(date)) {
// Extract the time portion of the date string to check if a timezone
// is specified. If not, add a Z to indicate UTC. We split to avoid
// then hyphens in the date portion.
const time = date.split('T')[1];
if (!time.includes('Z') && !time.includes('+') && !time.includes('-')) {
date += 'Z';
}
const dateObj = new Date(date);
if (Number.isNaN(dateObj.getTime())) {
const msg = 'Date is not a valid date';
return errors.InvalidArgument.customizeDescription(msg);
}
if (dateObj.getUTCHours() !== 0
|| dateObj.getUTCMinutes() !== 0
|| dateObj.getUTCSeconds() !== 0
|| dateObj.getUTCMilliseconds() !== 0) {
const msg = '\'Date\' must be at midnight GMT';
return errors.InvalidArgument.customizeDescription(msg);
}

View File

@ -80,6 +80,7 @@
"lint_md": "mdlint $(git ls-files '*.md')",
"lint_yml": "yamllint $(git ls-files '*.yml')",
"test": "jest tests/unit",
"test_auth": "jest tests/unit/auth",
"build": "tsc",
"prepare": "yarn build",
"ft_test": "jest tests/functional --testTimeout=120000 --forceExit",

View File

@ -420,6 +420,12 @@ describe('LifecycleConfiguration', () => {
assert.strictEqual(error, null);
});
it('should return no error with a valid ISO date at midnight with timezone', () => {
const date = '2024-01-08T06:00:00+06:00';
const error = lifecycleConfiguration._checkDate(date);
assert.strictEqual(error, null);
});
it('should return an error with a non-ISO date', () => {
const date = '2016-01-01T00:00:00000Z';
const error = lifecycleConfiguration._checkDate(date);
@ -436,6 +442,14 @@ describe('LifecycleConfiguration', () => {
expect(error.description).toEqual(msg);
});
it('should return an error with a non-ISO date', () => {
const date = '2024-01-08T00:00:00+34:00';
const error = lifecycleConfiguration._checkDate(date);
const msg = 'Date is not a valid date';
expect(error.is.InvalidArgument).toBeTruthy();
expect(error.description).toEqual(msg);
});
it('should return an error with a date that is not set to midnight', () => {
const date = '2024-01-04T15:22:40Z';
const error = lifecycleConfiguration._checkDate(date);
@ -443,6 +457,14 @@ describe('LifecycleConfiguration', () => {
expect(error.is.InvalidArgument).toBeTruthy();
expect(error.description).toEqual(msg);
});
it('should return an error with a date that is not set to midnight', () => {
const date = '2024-01-08T00:00:00.123Z';
const error = lifecycleConfiguration._checkDate(date);
const msg = '\'Date\' must be at midnight GMT';
expect(error.is.InvalidArgument).toBeTruthy();
expect(error.description).toEqual(msg);
});
});
});