mirror of
https://github.com/plankanban/planka.git
synced 2025-07-19 05:09:43 +02:00
parent
77ac2cf1b1
commit
2b4c2b0f49
40 changed files with 273 additions and 133 deletions
|
@ -49,7 +49,7 @@ module.exports = {
|
|||
}
|
||||
|
||||
return {
|
||||
item: sails.helpers.utils.signToken(user.id),
|
||||
item: sails.helpers.utils.createToken(user.id),
|
||||
};
|
||||
},
|
||||
};
|
||||
|
|
|
@ -54,6 +54,7 @@ module.exports = {
|
|||
{
|
||||
avatarDirname: files[0].extra.dirname,
|
||||
},
|
||||
currentUser,
|
||||
this.req,
|
||||
);
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ module.exports = {
|
|||
const values = _.pick(inputs, ['email']);
|
||||
|
||||
user = await sails.helpers.users
|
||||
.updateOne(user, values, this.req)
|
||||
.updateOne(user, values, currentUser, this.req)
|
||||
.intercept('emailAlreadyInUse', () => Errors.EMAIL_ALREADY_IN_USE);
|
||||
|
||||
if (!user) {
|
||||
|
|
|
@ -60,12 +60,21 @@ module.exports = {
|
|||
}
|
||||
|
||||
const values = _.pick(inputs, ['password']);
|
||||
user = await sails.helpers.users.updateOne(user, values, this.req);
|
||||
user = await sails.helpers.users.updateOne(user, values, currentUser, this.req);
|
||||
|
||||
if (!user) {
|
||||
throw Errors.USER_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (user.id === currentUser.id) {
|
||||
const accessToken = sails.helpers.utils.createToken(user.id, user.passwordUpdatedAt);
|
||||
|
||||
return {
|
||||
accessToken,
|
||||
item: user,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
item: user,
|
||||
};
|
||||
|
|
|
@ -71,7 +71,7 @@ module.exports = {
|
|||
const values = _.pick(inputs, ['username']);
|
||||
|
||||
user = await sails.helpers.users
|
||||
.updateOne(user, values, this.req)
|
||||
.updateOne(user, values, currentUser, this.req)
|
||||
.intercept('usernameAlreadyInUse', () => Errors.USERNAME_ALREADY_IN_USE);
|
||||
|
||||
if (!user) {
|
||||
|
|
|
@ -75,7 +75,7 @@ module.exports = {
|
|||
'subscribeToOwnCards',
|
||||
]);
|
||||
|
||||
user = await sails.helpers.users.updateOne(user, values, this.req);
|
||||
user = await sails.helpers.users.updateOne(user, values, currentUser, this.req);
|
||||
|
||||
if (!user) {
|
||||
throw Errors.USER_NOT_FOUND;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
const path = require('path');
|
||||
const bcrypt = require('bcrypt');
|
||||
const rimraf = require('rimraf');
|
||||
const { v4: uuid } = require('uuid');
|
||||
|
||||
module.exports = {
|
||||
inputs: {
|
||||
|
@ -35,6 +36,10 @@ module.exports = {
|
|||
},
|
||||
required: true,
|
||||
},
|
||||
user: {
|
||||
type: 'ref',
|
||||
required: true,
|
||||
},
|
||||
request: {
|
||||
type: 'ref',
|
||||
},
|
||||
|
@ -54,8 +59,10 @@ module.exports = {
|
|||
let isOnlyPasswordChange = false;
|
||||
|
||||
if (!_.isUndefined(inputs.values.password)) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
inputs.values.password = bcrypt.hashSync(inputs.values.password, 10);
|
||||
Object.assign(inputs.values, {
|
||||
password: bcrypt.hashSync(inputs.values.password, 10),
|
||||
passwordChangedAt: new Date().toUTCString(),
|
||||
});
|
||||
|
||||
if (Object.keys(inputs.values).length === 1) {
|
||||
isOnlyPasswordChange = true;
|
||||
|
@ -103,6 +110,29 @@ module.exports = {
|
|||
}
|
||||
}
|
||||
|
||||
if (!_.isUndefined(inputs.values.password)) {
|
||||
sails.sockets.broadcast(
|
||||
`user:${user.id}`,
|
||||
'userDelete', // TODO: introduce separate event
|
||||
{
|
||||
item: user,
|
||||
},
|
||||
inputs.request,
|
||||
);
|
||||
|
||||
if (user.id === inputs.user.id && inputs.request && inputs.request.isSocket) {
|
||||
const tempRoom = uuid();
|
||||
|
||||
sails.sockets.addRoomMembersToRooms(`user:${user.id}`, tempRoom, () => {
|
||||
sails.sockets.leave(inputs.request, tempRoom, () => {
|
||||
sails.sockets.leaveAll(tempRoom);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
sails.sockets.leaveAll(`user:${user.id}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isOnlyPasswordChange) {
|
||||
/* const projectIds = await sails.helpers.users.getManagerProjectIds(user.id);
|
||||
|
||||
|
|
29
server/api/helpers/utils/create-token.js
Normal file
29
server/api/helpers/utils/create-token.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
const jwt = require('jsonwebtoken');
|
||||
|
||||
module.exports = {
|
||||
sync: true,
|
||||
|
||||
inputs: {
|
||||
subject: {
|
||||
type: 'json',
|
||||
required: true,
|
||||
},
|
||||
issuedAt: {
|
||||
type: 'ref',
|
||||
},
|
||||
},
|
||||
|
||||
fn(inputs) {
|
||||
const { issuedAt = new Date() } = inputs;
|
||||
const iat = Math.floor(issuedAt / 1000);
|
||||
|
||||
return jwt.sign(
|
||||
{
|
||||
iat,
|
||||
sub: inputs.subject,
|
||||
exp: iat + sails.config.custom.tokenExpiresIn * 24 * 60 * 60,
|
||||
},
|
||||
sails.config.session.secret,
|
||||
);
|
||||
},
|
||||
};
|
|
@ -1,16 +0,0 @@
|
|||
const jwt = require('jsonwebtoken');
|
||||
|
||||
module.exports = {
|
||||
sync: true,
|
||||
|
||||
inputs: {
|
||||
payload: {
|
||||
type: 'json',
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
fn(inputs) {
|
||||
return jwt.sign(inputs.payload, sails.config.session.secret);
|
||||
},
|
||||
};
|
|
@ -15,10 +15,16 @@ module.exports = {
|
|||
},
|
||||
|
||||
fn(inputs) {
|
||||
let payload;
|
||||
try {
|
||||
return jwt.verify(inputs.token, sails.config.session.secret);
|
||||
payload = jwt.verify(inputs.token, sails.config.session.secret);
|
||||
} catch (error) {
|
||||
throw 'invalidToken';
|
||||
}
|
||||
|
||||
return {
|
||||
subject: payload.sub,
|
||||
issuedAt: new Date(payload.iat * 1000),
|
||||
};
|
||||
},
|
||||
};
|
||||
|
|
|
@ -10,15 +10,20 @@ module.exports = function defineCurrentUserHook(sails) {
|
|||
const TOKEN_PATTERN = /^Bearer /;
|
||||
|
||||
const getUser = async (accessToken) => {
|
||||
let id;
|
||||
|
||||
let payload;
|
||||
try {
|
||||
id = sails.helpers.utils.verifyToken(accessToken);
|
||||
payload = sails.helpers.utils.verifyToken(accessToken);
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return sails.helpers.users.getOne(id);
|
||||
const user = await sails.helpers.users.getOne(payload.subject);
|
||||
|
||||
if (user && user.passwordChangedAt > payload.issuedAt) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return user;
|
||||
};
|
||||
|
||||
return {
|
||||
|
@ -32,19 +37,23 @@ module.exports = function defineCurrentUserHook(sails) {
|
|||
|
||||
routes: {
|
||||
before: {
|
||||
'/*': {
|
||||
'/api/*': {
|
||||
async fn(req, res, next) {
|
||||
let accessToken;
|
||||
if (req.headers.authorization) {
|
||||
if (TOKEN_PATTERN.test(req.headers.authorization)) {
|
||||
accessToken = req.headers.authorization.replace(TOKEN_PATTERN, '');
|
||||
}
|
||||
} else if (req.cookies.accessToken) {
|
||||
accessToken = req.cookies.accessToken;
|
||||
const { authorization: authorizationHeader } = req.headers;
|
||||
|
||||
if (authorizationHeader && TOKEN_PATTERN.test(authorizationHeader)) {
|
||||
const accessToken = authorizationHeader.replace(TOKEN_PATTERN, '');
|
||||
|
||||
req.currentUser = await getUser(accessToken);
|
||||
}
|
||||
|
||||
if (accessToken) {
|
||||
req.currentUser = await getUser(accessToken);
|
||||
return next();
|
||||
},
|
||||
},
|
||||
'/attachments/*': {
|
||||
async fn(req, res, next) {
|
||||
if (req.cookies.accessToken) {
|
||||
req.currentUser = await getUser(req.cookies.accessToken);
|
||||
}
|
||||
|
||||
return next();
|
||||
|
|
|
@ -67,6 +67,10 @@ module.exports = {
|
|||
type: 'ref',
|
||||
columnName: 'deleted_at',
|
||||
},
|
||||
passwordChangedAt: {
|
||||
type: 'ref',
|
||||
columnName: 'password_changed_at',
|
||||
},
|
||||
|
||||
// ╔═╗╔╦╗╔╗ ╔═╗╔╦╗╔═╗
|
||||
// ║╣ ║║║╠╩╗║╣ ║║╚═╗
|
||||
|
@ -102,7 +106,7 @@ module.exports = {
|
|||
|
||||
customToJSON() {
|
||||
return {
|
||||
..._.omit(this, ['password', 'avatarDirname']),
|
||||
..._.omit(this, ['password', 'avatarDirname', 'passwordChangedAt']),
|
||||
avatarUrl:
|
||||
this.avatarDirname &&
|
||||
`${sails.config.custom.userAvatarsUrl}/${this.avatarDirname}/square-100.jpg`,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue