Before this change, when the test failed, the rejected promise
was not reported back to mocha and triggered "unhandled promise
rejection" warning only.
For scoped or related create method, the createOnlyInstance flag should
be calculated on the target model. For example, User.createAccessTokens
should set the flag only if AccessToken has updateonly properties.
Fix the code extracting current user id from the access token provided
in the HTTP request, to allow only access tokens created by the target
user models to execute the action.
This fixes the following security vulnerability:
* We have two user models, e.g. Admin and Customer
* We have an Admin instance and a Customer instance with the same
id and the same password.
* The Customer can change Admin's password using their
regular access token.
Fix the code extracting current user id from the access token provided
in the HTTP request, to allow only access tokens created by the target
user models to execute the action.
This fixes the following security vulnerability:
* A UserA with id 1 (for example), requires a resetToken1
* A UserB with the same id requires a resetToken2.
* Using resetToken2, use the UserAs/reset-password endpoint and change
the password of UserA and/or vice-versa.
- Fix `User.prototype.verify` to not modify properties of the supplied
`verifyOptions` argument. This is needed to allow callers to supply
the same options object to multiple calls of `verify`.
- Fix `User.getVerifyOptions` to always return a new copy of the
options object. This is needed to allow callers to modify the
returned options object without affecting the result returned
by subsequent calls of `getVerifyOptions`.
Fix the code resolving OWNER role to correctly handle the situation
where the target model has multiple "belongsTo" relations to the User
model.
Introduce a new model setting "ownerRelations" that enables the new
behavior. When "ownerRelations" is set to true, then all "belongsTo"
relations are considered as granting ownership. Alternatively,
"ownerRelations" can be set to an array of the relations which
are granting ownership.
For example, a document can "belongTo" an author and a reviewer,
but only the author is an owner, the reviewer is not. In this case,
"ownerRelations" should be set to "['author']".
When acl.resolvePermission was called with a request containing a
wildcard, it would return the matching acl with lowest score instead of
higher.
Fixes#2153
Reword the error message returned when the password is too long
- remove the plaintext password value, it looks very bad
- include information about the maximum allowed length instead
Also add additional context to the error.
- Remove flags and properly finish the stream.
- Destroy emits an end event for compability with ending of
ReadableStream now.
- Check for default implementation of destroy() method,
because in Node.js 8 all types of streams have a native one.
1. Make it possible to reuse getIdForRequest()
2. Introduce a flag to control if oAuth2 bearer token should be base64
encoded
3. Promote resolve() to locate/validate access tokens by id
This commit adds:
- user.prototype.verify(verifyOptions, options, cb)
- remote method /user/:id/verify
- User.getVerifyOptions()
The remote method can be used to replay the sending of a user
identity/email verification message.
`getVerifyOptions()` can be fully customized programmatically
or partially customized using user model's `.settings.verifyOptions`
`getVerifyOptions()` is called under the hood when calling the
/user/:id/verify remote method
`getVerifyOptions()` can also be used to ease the building
of identity verifyOptions:
```js
var verifyOptions = {
type: 'email',
from: 'noreply@example.com'
template: 'verify.ejs',
redirect: '/',
generateVerificationToken: function (user, options, cb) {
cb('random-token');
}
};
user.verify(verifyOptions);
```
NOTE: the `User.login()` has been modified to return the userId when
failing due to unverified identity/email. This userId can then be used
to call the /user/:id/verify remote method.
Improve the flow for setting/changing/resetting User password to make
it more secure.
1. Modify `User.resetPassword` to create a token scoped to allow
invocation of a single remote method: `User.setPassword`.
2. Scope the method `User.setPassword` so that regular tokens created
by `User.login` are not allowed to execute it.
For backwards compatibility, this new mode (flow) is enabled only
when User model setting `restrictResetPasswordTokenScope` is set to
`true`.
3. Changing the password via `User.prototype.patchAttributes`
(and similar DAO methods) is no longer allowed. Applications
must call `User.changePassword` and ask the user to provide
the current (old) password.
For backwards compatibility, this new mode (flow) is enabled only
when User model setting `rejectPasswordChangesViaPatchOrReplace` is set
to `true`.
Implement a new method for changing user password with password-reset
token but without the old password.
REST API
POST /api/users/reset-password
Authorization: your-password-reset-token-id
Content-Type: application/json
{"newPassword": "new-pass"}
JavaScript API
User.setPassword(userId, newPassword[, cb])
userInstance.setPassword(newPassword[, cb])
Note: the new REST endpoint is not protected by scopes yet, therefore
any valid access token can invoke it (similarly to how any valid access
token can change the password via PATCH /api/users/:id).
Fix the code builing a scoped method to correctly handle the case
when the setup method is called twice and the previously defined
method has to be overriden with new remoting metadata.
Define a new property `AccessToken.scopes` to contain the list of
scopes granted to this access token.
Define a new remote method metadata `accessScopes` to contain a list
of scope name required by this method.
Define a special built-in scope name "DEFAULT" that's used when
a method/token does not provide any scopes. This allows access
tokens to grant access to both the default scope and any additional
custom scopes at the same time.
Modify the authorization algorithm to ensure that at least one
of the scopes required by a remote method is allowed by the scopes
granted to the requesting access token.
The "DEFAULT" scope preserve backwards compatibility because existing
remote methods with no `accessScopes` can be accessed by (existing)
access tokens with no `scopes` defined.
Impact on existing applications:
- Database schema must be updated after upgrading the loopback version
- If the application was already using a custom `AccessToken.scopes`
property with a type different from an array, then the relevant code
must be updated to work with the new type "array of strings".
Currently any `currentUserLiteral` routes when accessed with a bad
token throw a 500 due to a SQL error that is raised because
`Model.findById` is invoked with `id={currentUserLiteral}`
(`id=me` in our case) when the url rewrite fails.
This commit changes the token middleware to return 401 Not Authorized
when the client is requesting a currentUserLiteral route without
a valid access token.