DB migrations
Google button
This commit is contained in:
@@ -14,7 +14,9 @@ router.post('hooks.unfurl', async ctx => {
|
||||
throw new AuthenticationError('Invalid token');
|
||||
|
||||
// TODO: Everything from here onwards will get moved to an async job
|
||||
const user = await User.find({ where: { slackId: event.user } });
|
||||
const user = await User.find({
|
||||
where: { service: 'slack', serviceId: event.user },
|
||||
});
|
||||
if (!user) return;
|
||||
|
||||
const auth = await Authentication.find({
|
||||
@@ -55,7 +57,8 @@ router.post('hooks.slack', async ctx => {
|
||||
|
||||
const user = await User.find({
|
||||
where: {
|
||||
slackId: user_id,
|
||||
service: 'slack',
|
||||
serviceId: user_id,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ describe('#hooks.unfurl', async () => {
|
||||
event: {
|
||||
type: 'link_shared',
|
||||
channel: 'Cxxxxxx',
|
||||
user: user.slackId,
|
||||
user: user.serviceId,
|
||||
message_ts: '123456789.9875',
|
||||
links: [
|
||||
{
|
||||
@@ -55,7 +55,7 @@ describe('#hooks.slack', async () => {
|
||||
const res = await server.post('/api/hooks.slack', {
|
||||
body: {
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
user_id: user.slackId,
|
||||
user_id: user.serviceId,
|
||||
text: 'dsfkndfskndsfkn',
|
||||
},
|
||||
});
|
||||
@@ -70,7 +70,7 @@ describe('#hooks.slack', async () => {
|
||||
const res = await server.post('/api/hooks.slack', {
|
||||
body: {
|
||||
token: process.env.SLACK_VERIFICATION_TOKEN,
|
||||
user_id: user.slackId,
|
||||
user_id: user.serviceId,
|
||||
text: document.title,
|
||||
},
|
||||
});
|
||||
@@ -98,7 +98,7 @@ describe('#hooks.slack', async () => {
|
||||
const res = await server.post('/api/hooks.slack', {
|
||||
body: {
|
||||
token: 'wrong-verification-token',
|
||||
user_id: user.slackId,
|
||||
user_id: user.serviceId,
|
||||
text: 'Welcome',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// @flow
|
||||
import Router from 'koa-router';
|
||||
import addMonths from 'date-fns/add_months';
|
||||
import { capitalize } from 'lodash';
|
||||
import { OAuth2Client } from 'google-auth-library';
|
||||
import { User, Team } from '../models';
|
||||
|
||||
@@ -32,17 +33,14 @@ router.get('google.callback', async ctx => {
|
||||
const response = await client.getToken(code);
|
||||
client.setCredentials(response.tokens);
|
||||
|
||||
console.log('Tokens acquired.');
|
||||
console.log(response.tokens);
|
||||
|
||||
const profile = await client.request({
|
||||
url: 'https://www.googleapis.com/oauth2/v1/userinfo',
|
||||
});
|
||||
|
||||
const teamName = profile.data.hd.split('.')[0];
|
||||
const teamName = capitalize(profile.data.hd.split('.')[0]);
|
||||
const [team, isFirstUser] = await Team.findOrCreate({
|
||||
where: {
|
||||
slackId: profile.data.hd,
|
||||
googleId: profile.data.hd,
|
||||
},
|
||||
defaults: {
|
||||
name: teamName,
|
||||
@@ -50,9 +48,10 @@ router.get('google.callback', async ctx => {
|
||||
},
|
||||
});
|
||||
|
||||
const [user, isFirstSignin] = await User.findOrCreate({
|
||||
const [user] = await User.findOrCreate({
|
||||
where: {
|
||||
slackId: profile.data.id,
|
||||
service: 'google',
|
||||
serviceId: profile.data.id,
|
||||
teamId: team.id,
|
||||
},
|
||||
defaults: {
|
||||
@@ -63,10 +62,6 @@ router.get('google.callback', async ctx => {
|
||||
},
|
||||
});
|
||||
|
||||
if (!isFirstSignin) {
|
||||
await user.save();
|
||||
}
|
||||
|
||||
if (isFirstUser) {
|
||||
await team.createFirstCollection(user.id);
|
||||
}
|
||||
@@ -77,7 +72,7 @@ router.get('google.callback', async ctx => {
|
||||
});
|
||||
ctx.cookies.set('accessToken', user.getJwtToken(), {
|
||||
httpOnly: false,
|
||||
expires: addMonths(new Date(), 6),
|
||||
expires: addMonths(new Date(), 1),
|
||||
});
|
||||
|
||||
ctx.redirect('/');
|
||||
|
||||
@@ -26,7 +26,9 @@ router.post('auth.slack', async ctx => {
|
||||
|
||||
const data = await Slack.oauthAccess(code);
|
||||
|
||||
let user = await User.findOne({ where: { slackId: data.user.id } });
|
||||
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;
|
||||
|
||||
@@ -48,7 +50,8 @@ router.post('auth.slack', async ctx => {
|
||||
await user.save();
|
||||
} else {
|
||||
user = await User.create({
|
||||
slackId: data.user.id,
|
||||
service: 'slack',
|
||||
serviceId: data.user.id,
|
||||
name: data.user.name,
|
||||
email: data.user.email,
|
||||
teamId: team.id,
|
||||
|
||||
27
server/migrations/20180528233909-google-auth.js
Normal file
27
server/migrations/20180528233909-google-auth.js
Normal file
@@ -0,0 +1,27 @@
|
||||
module.exports = {
|
||||
up: async (queryInterface, Sequelize) => {
|
||||
await queryInterface.addColumn('teams', 'googleId', {
|
||||
type: Sequelize.STRING,
|
||||
allowNull: true,
|
||||
unique: true
|
||||
});
|
||||
await queryInterface.addColumn('teams', 'avatarUrl', {
|
||||
type: Sequelize.STRING,
|
||||
allowNull: true,
|
||||
});
|
||||
await queryInterface.addColumn('users', 'service', {
|
||||
type: Sequelize.STRING,
|
||||
allowNull: true,
|
||||
defaultValue: 'slack'
|
||||
});
|
||||
await queryInterface.renameColumn('users', 'slackId', 'serviceId');
|
||||
await queryInterface.addIndex('teams', ['googleId']);
|
||||
},
|
||||
down: async (queryInterface, Sequelize) => {
|
||||
await queryInterface.removeColumn('teams', 'googleId');
|
||||
await queryInterface.removeColumn('teams', 'avatarUrl');
|
||||
await queryInterface.removeColumn('users', 'service');
|
||||
await queryInterface.renameColumn('users', 'serviceId', 'slackId');
|
||||
await queryInterface.removeIndex('teams', ['googleId']);
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,8 @@ const Team = sequelize.define(
|
||||
},
|
||||
name: DataTypes.STRING,
|
||||
slackId: { type: DataTypes.STRING, allowNull: true },
|
||||
googleId: { type: DataTypes.STRING, allowNull: true },
|
||||
avatarUrl: { type: DataTypes.STRING, allowNull: true },
|
||||
slackData: DataTypes.JSONB,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -25,7 +25,8 @@ const User = sequelize.define(
|
||||
passwordDigest: DataTypes.STRING,
|
||||
isAdmin: DataTypes.BOOLEAN,
|
||||
slackAccessToken: encryptedFields.vault('slackAccessToken'),
|
||||
slackId: { type: DataTypes.STRING, allowNull: true, unique: true },
|
||||
service: { type: DataTypes.STRING, allowNull: true, unique: true },
|
||||
serviceId: { type: DataTypes.STRING, allowNull: true, unique: true },
|
||||
slackData: DataTypes.JSONB,
|
||||
jwtSecret: encryptedFields.vault('jwtSecret'),
|
||||
suspendedAt: DataTypes.DATE,
|
||||
|
||||
@@ -3,6 +3,7 @@ import * as React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { signin } from '../../../shared/utils/routeHelpers';
|
||||
import Flex from '../../../shared/components/Flex';
|
||||
import GoogleLogo from '../../../shared/components/GoogleLogo';
|
||||
import SlackLogo from '../../../shared/components/SlackLogo';
|
||||
import { color } from '../../../shared/styles/constants';
|
||||
|
||||
@@ -10,22 +11,27 @@ type Props = {
|
||||
lastLoggedIn: string,
|
||||
};
|
||||
|
||||
const SlackSignin = ({ lastLoggedIn }: Props) => {
|
||||
const SignupButton = ({ lastLoggedIn }: Props) => {
|
||||
return (
|
||||
<Flex justify="center">
|
||||
<Flex>
|
||||
<Flex column>
|
||||
<Button href={signin('slack')}>
|
||||
<SlackLogo />
|
||||
<Spacer>Sign In with Slack</Spacer>
|
||||
</Button>
|
||||
{lastLoggedIn === 'slack' && 'You signed in with Slack previously'}
|
||||
<LastLogin>
|
||||
{lastLoggedIn === 'slack' && 'You signed in with Slack previously'}
|
||||
</LastLogin>
|
||||
</Flex>
|
||||
|
||||
<Flex>
|
||||
<Flex column>
|
||||
<Button href={signin('google')}>
|
||||
<GoogleLogo />
|
||||
<Spacer>Sign In with Google</Spacer>
|
||||
</Button>
|
||||
{lastLoggedIn === 'google' && 'You signed in with Google previously'}
|
||||
<LastLogin>
|
||||
{lastLoggedIn === 'google' && 'You signed in with Google previously'}
|
||||
</LastLogin>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
@@ -43,6 +49,13 @@ const Button = styled.a`
|
||||
background: ${color.black};
|
||||
border-radius: 4px;
|
||||
font-weight: 600;
|
||||
height: 56px;
|
||||
`;
|
||||
|
||||
export default SlackSignin;
|
||||
const LastLogin = styled.p`
|
||||
font-size: 12px;
|
||||
color: ${color.slate};
|
||||
padding-top: 4px;
|
||||
`;
|
||||
|
||||
export default SignupButton;
|
||||
|
||||
@@ -40,7 +40,8 @@ export async function buildUser(overrides: Object = {}) {
|
||||
username: `user${count}`,
|
||||
name: `User ${count}`,
|
||||
password: 'test123!',
|
||||
slackId: uuid.v4(),
|
||||
service: 'slack',
|
||||
serviceId: uuid.v4(),
|
||||
...overrides,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@ const seed = async () => {
|
||||
name: 'User 1',
|
||||
password: 'test123!',
|
||||
teamId: team.id,
|
||||
slackId: 'U2399UF2P',
|
||||
service: 'slack',
|
||||
serviceId: 'U2399UF2P',
|
||||
slackData: {
|
||||
id: 'U2399UF2P',
|
||||
image_192: 'http://example.com/avatar.png',
|
||||
@@ -45,7 +46,8 @@ const seed = async () => {
|
||||
password: 'test123!',
|
||||
teamId: team.id,
|
||||
isAdmin: true,
|
||||
slackId: 'U2399UF1P',
|
||||
service: 'slack',
|
||||
serviceId: 'U2399UF1P',
|
||||
slackData: {
|
||||
id: 'U2399UF1P',
|
||||
image_192: 'http://example.com/avatar.png',
|
||||
|
||||
Reference in New Issue
Block a user