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

[SEMVER-MAJOR] Fix rest-coercion of timestamp strings #349

Merged
merged 1 commit into from Sep 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions 3.0-RELEASE-NOTES.md
Expand Up @@ -168,6 +168,11 @@ Most notable breaking changes:
'true', 'false', '0' and '1'
Values are case-insensitive, i.e. 'TRUE' and 'FaLsE' work too.
- Date type detects "Invalid Date" and rejects such requests.
- When converting a value coming from a string source like querystring
to a date, and the value is a timestamp (i.e. an integer), we treat
the value as a number now. That way the value "0" always produces
"1970-01-01T00:00:00.000Z" instead of some date around 1999/2000/2001
depending on server timezone.

Hopefully this change should leave most LoopBack applications (and clients)
unaffected. If your start seeing unusual amount of 400 error responses after
Expand Down
8 changes: 6 additions & 2 deletions lib/types/date.js
Expand Up @@ -28,8 +28,12 @@ module.exports = {
if (value === '')
return { value: undefined };

// we don't have any special sloppy conversion yet
// TODO(bajtos) convert numeric strings to numbers first
if (/^-?[0-9]+$/.test(value)) {
// convert a timestamp string to a number
// that way ?from=0 produces 1970-01-01T00:00:00.000Z
value = +value;
}

return this.fromTypedValue(ctx, value);
},

Expand Down
4 changes: 2 additions & 2 deletions test/rest-coercion/urlencoded-array.suite.js
Expand Up @@ -196,8 +196,8 @@ function suite(prefix, ctx) {
['arg=null', null],

// Valid values - repeated keys
['arg=0', [new Date('0')]], // 1999-12-31T23:00:00.000Z in CEST
['arg=1', [new Date('1')]], // 2000-12-31T23:00:00.000Z
['arg=0', [new Date('1970-01-01T00:00:00.000Z')]],
['arg=1', [new Date('1970-01-01T00:00:00.001Z')]],
['arg=2016-05-19T13:28:51.299Z',
[new Date('2016-05-19T13:28:51.299Z')]],
['arg=2016-05-19T13:28:51.299Z&arg=2016-05-20T08:27:28.539Z', [
Expand Down
19 changes: 8 additions & 11 deletions test/rest-coercion/urlencoded-date.suite.js
Expand Up @@ -50,18 +50,15 @@ function suite(prefix, ctx) {
['arg=Thu+May+19+2016+15:28:51+GMT+0200+(CEST)',
new Date('2016-05-19T15:28:51.000Z')],

// NOTE(bajtos) should we convert the numeric values into a number
// before passing it to the Date constructor?
// That way ?arg=0 would produce '1970-01-01T00:00:00.000Z', which is
// Integer values are converted to a number before passing it to
// the Date constructor
// That way ?arg=0 produces '1970-01-01T00:00:00.000Z', which is
// arguably more expected then some date around 1999/2000/2001
// Also note that with the current implementation, the parsed
// value depends on the timezone of the server, therefore
// we cannot specify exact date values here in the test
// and have to use the same Date input as in the HTTP request :(
// See also https://github.com/strongloop/strong-remoting/issues/238
['arg=0', new Date('0')], // 1999-12-31T23:00:00.000Z in CEST
['arg=1', new Date('1')], // 2000-12-31T23:00:00.000Z
['arg=-1', new Date('-1')], // 2000-12-31T23:00:00.000Z
['arg=0', new Date('1970-01-01T00:00:00.000Z')],
['arg=1', new Date('1970-01-01T00:00:00.001Z')],
['arg=-1', new Date('1969-12-31T23:59:59.999Z')],

// Non-integer numbers are treated as strings.
['arg=1.2', new Date('1.2')], // 2001-01-01T23:00:00.000Z
['arg=-1.2', new Date('-1.2')], // 2001-01-01T23:00:00.000Z

Expand Down