Move slack auth handling entirely to server
This commit is contained in:
@@ -1,97 +1,86 @@
|
||||
// @flow
|
||||
import Router from 'koa-router';
|
||||
import addHours from 'date-fns/add_hours';
|
||||
import addMonths from 'date-fns/add_months';
|
||||
import auth from '../middlewares/authentication';
|
||||
import { slackAuth } from '../../shared/utils/routeHelpers';
|
||||
import { presentUser, presentTeam } from '../presenters';
|
||||
import { Authentication, Integration, User, Team } from '../models';
|
||||
import * as Slack from '../slack';
|
||||
|
||||
const router = new Router();
|
||||
|
||||
router.get('auth.slack', async ctx => {
|
||||
// start the oauth process and redirect user to Slack
|
||||
router.get('slack', async ctx => {
|
||||
const state = Math.random()
|
||||
.toString(36)
|
||||
.substring(7);
|
||||
|
||||
ctx.cookies.set('state', state, {
|
||||
httpOnly: false,
|
||||
expires: new Date('2100'),
|
||||
expires: addHours(new Date(), 1),
|
||||
});
|
||||
ctx.redirect(slackAuth(state));
|
||||
});
|
||||
|
||||
router.post('auth.slack', async ctx => {
|
||||
const { code } = ctx.body;
|
||||
ctx.assertPresent(code, 'code is required');
|
||||
// signin callback from Slack
|
||||
router.get('slack.callback', async ctx => {
|
||||
const { code, error, state } = ctx.request.query;
|
||||
ctx.assertPresent(code || error, 'code is required');
|
||||
ctx.assertPresent(state, 'state is required');
|
||||
|
||||
if (state !== ctx.cookies.get('state') || error) {
|
||||
ctx.redirect('/?notice=auth-error');
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await Slack.oauthAccess(code);
|
||||
|
||||
let user = await User.findOne({
|
||||
where: { service: 'slack', serviceId: data.user.id },
|
||||
});
|
||||
let team = await Team.findOne({ where: { slackId: data.team.id } });
|
||||
const isFirstUser = !team;
|
||||
|
||||
if (team) {
|
||||
team.name = data.team.name;
|
||||
team.slackData = data.team;
|
||||
await team.save();
|
||||
} else {
|
||||
team = await Team.create({
|
||||
name: data.team.name,
|
||||
const [team, isFirstUser] = await Team.findOrCreate({
|
||||
where: {
|
||||
slackId: data.team.id,
|
||||
slackData: data.team,
|
||||
});
|
||||
}
|
||||
},
|
||||
defaults: {
|
||||
name: data.team.name,
|
||||
avatarUrl: data.team.image_88,
|
||||
},
|
||||
});
|
||||
|
||||
if (user) {
|
||||
user.slackAccessToken = data.access_token;
|
||||
user.slackData = data.user;
|
||||
await user.save();
|
||||
} else {
|
||||
user = await User.create({
|
||||
const [user] = await User.findOrCreate({
|
||||
where: {
|
||||
service: 'slack',
|
||||
serviceId: data.user.id,
|
||||
teamId: team.id,
|
||||
},
|
||||
defaults: {
|
||||
name: data.user.name,
|
||||
email: data.user.email,
|
||||
teamId: team.id,
|
||||
isAdmin: isFirstUser,
|
||||
slackData: data.user,
|
||||
slackAccessToken: data.access_token,
|
||||
});
|
||||
|
||||
// Set initial avatar
|
||||
await user.updateAvatar();
|
||||
await user.save();
|
||||
}
|
||||
avatarUrl: data.user.image_192,
|
||||
},
|
||||
});
|
||||
|
||||
if (isFirstUser) {
|
||||
await team.createFirstCollection(user.id);
|
||||
}
|
||||
|
||||
// Signal to backend that the user is logged in.
|
||||
// This is only used to signal SSR rendering, not
|
||||
// used for auth.
|
||||
ctx.cookies.set('loggedIn', 'true', {
|
||||
ctx.cookies.set('lastSignedIn', 'slack', {
|
||||
httpOnly: false,
|
||||
expires: new Date('2100'),
|
||||
});
|
||||
ctx.cookies.set('accessToken', user.getJwtToken(), {
|
||||
httpOnly: false,
|
||||
expires: addMonths(new Date(), 1),
|
||||
});
|
||||
|
||||
ctx.body = {
|
||||
data: {
|
||||
user: await presentUser(ctx, user),
|
||||
team: await presentTeam(ctx, team),
|
||||
accessToken: user.getJwtToken(),
|
||||
},
|
||||
};
|
||||
ctx.redirect('/');
|
||||
});
|
||||
|
||||
router.post('auth.slackCommands', auth(), async ctx => {
|
||||
router.post('slack.commands', auth(), async ctx => {
|
||||
const { code } = ctx.body;
|
||||
ctx.assertPresent(code, 'code is required');
|
||||
|
||||
const user = ctx.state.user;
|
||||
const endpoint = `${process.env.URL || ''}/auth/slack/commands`;
|
||||
const endpoint = `${process.env.URL || ''}/auth/slack.commands`;
|
||||
const data = await Slack.oauthAccess(code, endpoint);
|
||||
const serviceId = 'slack';
|
||||
|
||||
@@ -112,12 +101,12 @@ router.post('auth.slackCommands', auth(), async ctx => {
|
||||
});
|
||||
});
|
||||
|
||||
router.post('auth.slackPost', auth(), async ctx => {
|
||||
router.post('slack.post', auth(), async ctx => {
|
||||
const { code, collectionId } = ctx.body;
|
||||
ctx.assertPresent(code, 'code is required');
|
||||
|
||||
const user = ctx.state.user;
|
||||
const endpoint = `${process.env.URL || ''}/auth/slack/post`;
|
||||
const endpoint = `${process.env.URL || ''}/auth/slack.post`;
|
||||
const data = await Slack.oauthAccess(code, endpoint);
|
||||
const serviceId = 'slack';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user