Steps to reproduce
1. Generate google access token in Frontend(I am using React library `react-google-login`)
2.Login using `local` strategy using email A(User A)
POST /authentication
body
{
"strategy": "local",
"email": "{{email A}}",
"password": "{{password}}"
}
3.Login as User B using `google` strategy of using jwt token(generated in step 2) in Authorization of account A
POST /authentication
body
{
"strategy": "google",
"access_token": "<google access token in step 1>"
}
Expected behavior
User B created.
Actual behavior
User B created, while User A is deleted in Database
Code
authentication.js
const { AuthenticationService, AuthenticationBaseStrategy, JWTStrategy } = require('@feathersjs/authentication');
const { LocalStrategy } = require('@feathersjs/authentication-local');
const { expressOauth } = require('@feathersjs/authentication-oauth');
const { discard, iff, isProvider, lowerCase, keep } = require('feathers-hooks-common')
const { OAuthStrategy } = require('@feathersjs/authentication-oauth');
class GoogleStrategy extends OAuthStrategy {
async getEntityData(profile) {
// this will set 'googleId'
const baseData = await super.getEntityData(profile);
const existingOauthEntity = await super.findEntity(profile)
// Check if user already exist
if(existingOauthEntity){
return {
...baseData
}
}else{
return {
...baseData,
email: profile.email,
};
}
}
}
module.exports = app => {
const authentication = new AuthenticationService(app);
authentication.register('jwt', new JWTStrategy());
authentication.register('local', new LocalStrategy());
authentication.register('google', new GoogleStrategy());
app.use('/authentication', authentication);
app.configure(expressOauth());
app.service('authentication').hooks({
before: {},
after: {
create: [
discard('authentication')
]
}
});
};
users.hook.js
const { iff, isProvider, keep, required, disallow, disablePagination, preventChanges, sequelizeConvert} = require('feathers-hooks-common');
const { authenticate } = require('@feathersjs/authentication').hooks;
const checkPermissions = require('feathers-permissions');
const errors = require('@feathersjs/errors');
const {
hashPassword, protect
} = require('@feathersjs/authentication-local').hooks;
module.exports = {
before: {
all: [
sequelizeConvert({
isEmailVerified: 'boolean',
}),
],
find: [
iff(isProvider('external'),
authenticate('jwt'),
checkPermissions({
roles: [ 'superadmin', 'admin'],
error: true,
})
)
],
get: [
iff(isProvider('external'),
iff(!(context => {return (context.params.authStrategies[0] === 'google')}),
authenticate('jwt'),
checkPermissions({
roles: [ 'admin'],
error: true,
})
)
)
],
create: [
iff(isProvider('external'),
iff((context => !context.params.authStrategies) || (context => !(context.params.authStrategies[0] === 'google')),
authenticate('jwt'),
checkPermissions({
roles: [ 'admin'],
error: true,
}),
required('email', 'password'),
hashPassword('password'),
)
)
],
update: [disallow()],
patch: [
iff(isProvider('external'),
preventChanges(true, [
'id',
'password',
'passwordResetEmailToken',
'passwordResetToken',
'passwordResetRequestedAt',
'passwordResetExpiresAt',
]),
authenticate('jwt'),
checkPermissions({
roles: ['admin'],
error: false,
}),
)
],
},
after: {
all: [
sequelizeConvert({
isEmailVerified: 'boolean',
}),
protect(
'password',
'passwordResetEmailToken'
)
],
find: [],
get: [],
create: [],
update: [disallow('external')],
patch: [],
remove: []
},
};