Merge pull request #329 from jorilallo/jori/avatar-s3
Upload avatars to S3
This commit is contained in:
@ -47,6 +47,10 @@ router.post('auth.slack', async ctx => {
|
||||
await team.createFirstCollection(user.id);
|
||||
}
|
||||
|
||||
// Update user's avatar
|
||||
await user.updateAvatar();
|
||||
await user.save();
|
||||
|
||||
ctx.body = {
|
||||
data: {
|
||||
user: await presentUser(ctx, user),
|
||||
|
12
server/migrations/20171019071915-user-avatar-url.js
Normal file
12
server/migrations/20171019071915-user-avatar-url.js
Normal file
@ -0,0 +1,12 @@
|
||||
module.exports = {
|
||||
up: function(queryInterface, Sequelize) {
|
||||
queryInterface.addColumn('users', 'avatarUrl', {
|
||||
type: Sequelize.TEXT,
|
||||
allowNull: true,
|
||||
});
|
||||
},
|
||||
|
||||
down: function(queryInterface, Sequelize) {
|
||||
queryInterface.removeColumn('users', 'avatarUrl');
|
||||
},
|
||||
};
|
@ -1,7 +1,9 @@
|
||||
// @flow
|
||||
import crypto from 'crypto';
|
||||
import bcrypt from 'bcrypt';
|
||||
import uuid from 'uuid';
|
||||
import { DataTypes, sequelize, encryptedFields } from '../sequelize';
|
||||
import { uploadToS3FromUrl } from '../utils/s3';
|
||||
|
||||
import JWT from 'jsonwebtoken';
|
||||
|
||||
@ -18,6 +20,7 @@ const User = sequelize.define(
|
||||
email: { type: DataTypes.STRING },
|
||||
username: { type: DataTypes.STRING },
|
||||
name: DataTypes.STRING,
|
||||
avatarUrl: { type: DataTypes.STRING, allowNull: true },
|
||||
password: DataTypes.VIRTUAL,
|
||||
passwordDigest: DataTypes.STRING,
|
||||
isAdmin: DataTypes.BOOLEAN,
|
||||
@ -66,6 +69,12 @@ User.prototype.verifyPassword = function(password) {
|
||||
});
|
||||
});
|
||||
};
|
||||
User.prototype.updateAvatar = async function() {
|
||||
this.avatarUrl = await uploadToS3FromUrl(
|
||||
this.slackData.image_192,
|
||||
`avatars/${this.id}/${uuid.v4()}`
|
||||
);
|
||||
};
|
||||
|
||||
const setRandomJwtSecret = model => {
|
||||
model.jwtSecret = crypto.randomBytes(64).toString('hex');
|
||||
|
@ -8,7 +8,8 @@ function present(ctx: Object, user: User) {
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
name: user.name,
|
||||
avatarUrl: user.slackData ? user.slackData.image_192 : null,
|
||||
avatarUrl: user.avatarUrl ||
|
||||
(user.slackData ? user.slackData.image_192 : null),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,18 @@
|
||||
// @flow
|
||||
import crypto from 'crypto';
|
||||
import moment from 'moment';
|
||||
import AWS from 'aws-sdk';
|
||||
import invariant from 'invariant';
|
||||
import fetch from 'isomorphic-fetch';
|
||||
import bugsnag from 'bugsnag';
|
||||
|
||||
AWS.config.update({
|
||||
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
||||
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
||||
});
|
||||
|
||||
const AWS_SECRET_ACCESS_KEY = process.env.AWS_SECRET_ACCESS_KEY;
|
||||
const AWS_S3_UPLOAD_BUCKET_NAME = process.env.AWS_S3_UPLOAD_BUCKET_NAME;
|
||||
|
||||
const makePolicy = () => {
|
||||
const policy = {
|
||||
@ -19,13 +32,37 @@ const makePolicy = () => {
|
||||
return new Buffer(JSON.stringify(policy)).toString('base64');
|
||||
};
|
||||
|
||||
const signPolicy = policy => {
|
||||
const signPolicy = (policy: any) => {
|
||||
invariant(AWS_SECRET_ACCESS_KEY, 'AWS_SECRET_ACCESS_KEY not set');
|
||||
const signature = crypto
|
||||
.createHmac('sha1', process.env.AWS_SECRET_ACCESS_KEY)
|
||||
.createHmac('sha1', AWS_SECRET_ACCESS_KEY)
|
||||
.update(policy)
|
||||
.digest('base64');
|
||||
|
||||
return signature;
|
||||
};
|
||||
|
||||
export { makePolicy, signPolicy };
|
||||
const uploadToS3FromUrl = async (url: string, key: string) => {
|
||||
const s3 = new AWS.S3();
|
||||
invariant(AWS_S3_UPLOAD_BUCKET_NAME, 'AWS_S3_UPLOAD_BUCKET_NAME not set');
|
||||
|
||||
try {
|
||||
// $FlowIssue dunno it's fine
|
||||
const res = await fetch(url);
|
||||
const buffer = await res.buffer();
|
||||
await s3
|
||||
.putObject({
|
||||
Bucket: process.env.AWS_S3_UPLOAD_BUCKET_NAME,
|
||||
Key: key,
|
||||
ContentType: res.headers['content-type'],
|
||||
ContentLength: res.headers['content-length'],
|
||||
Body: buffer,
|
||||
})
|
||||
.promise();
|
||||
return `https://s3.amazonaws.com/${AWS_S3_UPLOAD_BUCKET_NAME}/${key}`;
|
||||
} catch (e) {
|
||||
bugsnag.notify(e);
|
||||
}
|
||||
};
|
||||
|
||||
export { makePolicy, signPolicy, uploadToS3FromUrl };
|
||||
|
Reference in New Issue
Block a user