Save avatars to le cloud in beforeSave hooks
Added encryption to uploads Updated icon for team settings
This commit is contained in:
@ -7,6 +7,7 @@ import {
|
||||
CodeIcon,
|
||||
UserIcon,
|
||||
LinkIcon,
|
||||
TeamIcon,
|
||||
} from 'outline-icons';
|
||||
|
||||
import Flex from 'shared/components/Flex';
|
||||
@ -55,7 +56,7 @@ class SettingsSidebar extends React.Component<Props> {
|
||||
<Section>
|
||||
<Header>Team</Header>
|
||||
{user.isAdmin && (
|
||||
<SidebarLink to="/settings/details" icon={<SettingsIcon />}>
|
||||
<SidebarLink to="/settings/details" icon={<TeamIcon />}>
|
||||
Details
|
||||
</SidebarLink>
|
||||
)}
|
||||
|
@ -45,7 +45,7 @@ class DropToImport extends React.Component<Props> {
|
||||
const asset = await uploadFile(imageBlob, { name: this.file.name });
|
||||
this.props.onSuccess(asset.url);
|
||||
} catch (err) {
|
||||
this.props.onError(err);
|
||||
this.props.onError(err.message);
|
||||
} finally {
|
||||
this.isUploading = false;
|
||||
this.isCropping = false;
|
||||
|
@ -133,7 +133,7 @@
|
||||
"nodemailer": "^4.4.0",
|
||||
"normalize.css": "^7.0.0",
|
||||
"normalizr": "2.0.1",
|
||||
"outline-icons": "^1.1.0",
|
||||
"outline-icons": "^1.2.0",
|
||||
"oy-vey": "^0.10.0",
|
||||
"pg": "^6.1.5",
|
||||
"pg-hstore": "2.3.2",
|
||||
|
@ -1,5 +1,7 @@
|
||||
// @flow
|
||||
import uuid from 'uuid';
|
||||
import { DataTypes, sequelize, Op } from '../sequelize';
|
||||
import { publicS3Endpoint, uploadToS3FromUrl } from '../utils/s3';
|
||||
import Collection from './Collection';
|
||||
import User from './User';
|
||||
|
||||
@ -33,6 +35,18 @@ Team.associate = models => {
|
||||
Team.hasMany(models.User, { as: 'users' });
|
||||
};
|
||||
|
||||
const uploadAvatar = async model => {
|
||||
const endpoint = publicS3Endpoint();
|
||||
|
||||
if (model.avatarUrl && !model.avatarUrl.startsWith(endpoint)) {
|
||||
const newUrl = await uploadToS3FromUrl(
|
||||
model.avatarUrl,
|
||||
`avatars/${model.id}/${uuid.v4()}`
|
||||
);
|
||||
if (newUrl) model.avatarUrl = newUrl;
|
||||
}
|
||||
};
|
||||
|
||||
Team.prototype.createFirstCollection = async function(userId) {
|
||||
return await Collection.create({
|
||||
name: 'General',
|
||||
@ -82,4 +96,6 @@ Team.prototype.activateUser = async function(user: User, admin: User) {
|
||||
});
|
||||
};
|
||||
|
||||
Team.beforeSave(uploadAvatar);
|
||||
|
||||
export default Team;
|
||||
|
@ -4,7 +4,7 @@ import bcrypt from 'bcrypt';
|
||||
import uuid from 'uuid';
|
||||
import JWT from 'jsonwebtoken';
|
||||
import { DataTypes, sequelize, encryptedFields } from '../sequelize';
|
||||
import { uploadToS3FromUrl } from '../utils/s3';
|
||||
import { publicS3Endpoint, uploadToS3FromUrl } from '../utils/s3';
|
||||
import { sendEmail } from '../mailer';
|
||||
|
||||
const BCRYPT_COST = process.env.NODE_ENV !== 'production' ? 4 : 12;
|
||||
@ -57,9 +57,7 @@ User.associate = models => {
|
||||
User.prototype.getJwtToken = function() {
|
||||
return JWT.sign({ id: this.id }, this.jwtSecret);
|
||||
};
|
||||
User.prototype.getTeam = async function() {
|
||||
return this.team;
|
||||
};
|
||||
|
||||
User.prototype.verifyPassword = function(password) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.passwordDigest) {
|
||||
@ -77,17 +75,23 @@ User.prototype.verifyPassword = function(password) {
|
||||
});
|
||||
});
|
||||
};
|
||||
User.prototype.updateAvatar = async function() {
|
||||
this.avatarUrl = await uploadToS3FromUrl(
|
||||
this.slackData.image_192,
|
||||
`avatars/${this.id}/${uuid.v4()}`
|
||||
|
||||
const uploadAvatar = async model => {
|
||||
const endpoint = publicS3Endpoint();
|
||||
|
||||
if (model.avatarUrl && !model.avatarUrl.startsWith(endpoint)) {
|
||||
const newUrl = await uploadToS3FromUrl(
|
||||
model.avatarUrl,
|
||||
`avatars/${model.id}/${uuid.v4()}`
|
||||
);
|
||||
if (newUrl) model.avatarUrl = newUrl;
|
||||
}
|
||||
};
|
||||
|
||||
const setRandomJwtSecret = model => {
|
||||
model.jwtSecret = crypto.randomBytes(64).toString('hex');
|
||||
};
|
||||
const hashPassword = function hashPassword(model) {
|
||||
const hashPassword = model => {
|
||||
if (!model.password) {
|
||||
return null;
|
||||
}
|
||||
@ -106,6 +110,7 @@ const hashPassword = function hashPassword(model) {
|
||||
};
|
||||
User.beforeCreate(hashPassword);
|
||||
User.beforeUpdate(hashPassword);
|
||||
User.beforeSave(uploadAvatar);
|
||||
User.beforeCreate(setRandomJwtSecret);
|
||||
User.afterCreate(user => sendEmail('welcome', user.email));
|
||||
|
||||
|
@ -68,6 +68,7 @@ export const uploadToS3FromUrl = async (url: string, key: string) => {
|
||||
Key: key,
|
||||
ContentType: res.headers['content-type'],
|
||||
ContentLength: res.headers['content-length'],
|
||||
ServerSideEncryption: 'AES256',
|
||||
Body: buffer,
|
||||
})
|
||||
.promise();
|
||||
|
@ -7326,9 +7326,9 @@ outline-icons@^1.0.0:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/outline-icons/-/outline-icons-1.0.3.tgz#f0928a8bbc7e7ff4ea6762eee8fb2995d477941e"
|
||||
|
||||
outline-icons@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/outline-icons/-/outline-icons-1.1.0.tgz#08eb188a97a1aa8970a4dded7841c3d8b96b8577"
|
||||
outline-icons@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/outline-icons/-/outline-icons-1.2.0.tgz#8a0e0e9e9b98336470228837c4933ba10297fcf5"
|
||||
|
||||
oy-vey@^0.10.0:
|
||||
version "0.10.0"
|
||||
|
Reference in New Issue
Block a user