Commit 5799ae7c authored by nanahira's avatar nanahira

rework

parent 4df46f05
let config = process.env['NODE_ENV'] == 'development' ? require('./conf-dev').default : {
DATABASE: process.env['DATABASE'],
synchronize: !process.env['DB_NO_SYNC'],
Mail: {
SMTP_HOST: process.env['SMTP_HOST'],
SMTP_USERNAME: process.env['SMTP_USERNAME'],
......
This diff is collapsed.
......@@ -21,8 +21,8 @@
"log4js": "^1.1.1",
"mime": "^1.3.4",
"nodemailer": "^3.1.8",
"pg": "^6.1.5",
"typeorm": "^0.0.11",
"pg": "^8.7.1",
"typeorm": "^0.2.37",
"uuid": "^3.0.1"
},
"devDependencies": {
......
......@@ -7,6 +7,7 @@ import privateRouter from './src/privateRoutes';
import { createConnection } from 'typeorm';
import config from './config';
import {Token, User, UserNameChangeHistory} from './src/model';
import { setConnection } from './src/controllers/entity-manager';
const app = new Koa();
......@@ -65,18 +66,17 @@ app.use(privateRouter.allowedMethods());
async function main() {
console.log('Creating database connection.');
try {
await createConnection({
driver: {
type: 'postgres',
url: config.DATABASE
},
const conn = await createConnection({
type: 'postgres',
url: config.DATABASE,
entities: [User, Token, UserNameChangeHistory],
autoSchemaSync: true,
logging: {
synchronize: config.synchronize,
/*logging: {
logQueries: process.env['NODE_ENV'] === 'development',
logFailedQueryError: process.env['NODE_ENV'] === 'development',
}
}*/
});
setConnection(conn);
console.log('Starting server.');
app.listen(3000, () => {
console.log('Server is running at port %s', 3000);
......
import { Context } from 'koa';
import { SignIn, SignUp, Token, User } from '../model';
import * as crypto from 'crypto';
import { getEntityManager } from 'typeorm';
import { getEntityManager } from './entity-manager';
import * as Bluebird from 'bluebird';
import tp from '../mail';
import * as uuid from 'uuid';
......@@ -95,7 +95,7 @@ export const signup = async (ctx: Context) => {
ip_address: ctx.request.ip
});
const user = await getEntityManager().persist(newUser);
const user = await getEntityManager().save(newUser);
const key = uuid.v1();
let _token: Token = new Token({
......@@ -105,7 +105,7 @@ export const signup = async (ctx: Context) => {
type: 'activate'
});
await getEntityManager().persist(_token);
await getEntityManager().save(_token);
const url = new URL('https://accounts.moecube.com/activate');
url.searchParams.set('key', key);
......@@ -117,7 +117,7 @@ export const signup = async (ctx: Context) => {
text: `单击链接 或将链接复制到网页地址栏并回车 来激活账号 ${url}`,
html: views.activate({ locale: 'zh-CN', username: user.username, url })
}).catch(function(error) {
console.log(`Failed to send mail to ${user.username}<${user.email}>`);
console.log(`Failed to send mail to ${user.username}<${user.email}>: ${error.toString()}`);
});
const token = createToken({
......@@ -160,7 +160,7 @@ export const forgot = async (ctx: Context) => {
});
await getEntityManager().persist(token);
await getEntityManager().save(token);
const url = new URL('https://accounts.moecube.com/reset');
url.searchParams.set('key', key);
......@@ -194,7 +194,7 @@ export const resetPassword = async (ctx: Context) => {
}
const userRep = getEntityManager().getRepository(User);
let user: User | undefined = await userRep.findOneById(u.user_id);
let user: User | undefined = await userRep.findOne({where: {id: u.user_id}});
if (!user) {
ctx.throw('i_user_unexists', 400);
......@@ -206,7 +206,7 @@ export const resetPassword = async (ctx: Context) => {
user.password_hash = (await Bluebird.promisify(crypto.pbkdf2)(u.password, salt, 64000, 32, 'sha256')).toString('hex');
user.salt = salt;
ctx.body = await getEntityManager().persist(user);
ctx.body = await getEntityManager().save(user);
await tokenReq.remove(token);
......@@ -235,7 +235,7 @@ export const activate = async (ctx: Context) => {
user.active = true;
user.email = token.data;
ctx.body = await userReq.persist(user);
ctx.body = await userReq.save(user);
let tokens: Token[] = await tokenReq.find({ user_id: user.id, type: 'activate' });
......@@ -249,5 +249,9 @@ export const authUser = async (ctx: Context) => {
const userReq = getEntityManager().getRepository(User);
ctx.status = 200;
ctx.body = await userReq.findOne({ id: user.id });
};
\ No newline at end of file
const gotUser = await userReq.findOne({ id: user.id });
if (gotUser) {
gotUser.cleanSensitiveData()
}
ctx.body = gotUser;
};
import { Connection } from "typeorm"
let connection: Connection;
export function setConnection(conn: Connection) {
connection = conn;
}
export function getEntityManager() {
return connection.manager;
}
......@@ -2,7 +2,7 @@ import { Context } from 'koa';
import {Token, User, UserNameChangeHistory} from '../model';
import * as crypto from 'crypto';
import * as Bluebird from 'bluebird';
import { getEntityManager } from 'typeorm';
import { getEntityManager } from './entity-manager';
import tp from '../mail';
import config from '../../config';
import * as uuid from 'uuid';
......@@ -42,7 +42,7 @@ export const checkUserExists = async (ctx: Context) => {
if (user) {
ctx.body = user;
ctx.body = user.cleanSensitiveData();
} else {
ctx.throw('i_not_found', 400);
}
......@@ -76,10 +76,10 @@ export const UpdateProfiles = async (ctx: Context) => {
Object.assign(_user, ctx.request.body);
await getEntityManager().persist(_user);
await getEntityManager().save(_user);
ctx.status = 200;
ctx.body = _user;
ctx.body = _user.cleanSensitiveData();
};
......@@ -137,7 +137,7 @@ export const UpdateAccount = async (ctx: Context) => {
if (u.username != user.username) {
const historyRep = getEntityManager().getRepository(UserNameChangeHistory);
let changeHistory = new UserNameChangeHistory(user.username, u.username, u.user_id);
historyRep.persist(changeHistory);
historyRep.save(changeHistory);
}
user.username = u.username;
......@@ -164,7 +164,7 @@ export const UpdateAccount = async (ctx: Context) => {
type: 'activate',
});
await getEntityManager().persist(token);
await getEntityManager().save(token);
const url = new URL('https://accounts.moecube.com/activate');
url.searchParams.set('key', key);
......@@ -184,7 +184,7 @@ export const UpdateAccount = async (ctx: Context) => {
}
ctx.status = 200;
ctx.body = await userRep.persist(user);
ctx.body = (await userRep.save(user)).cleanSensitiveData();
};
......@@ -194,6 +194,7 @@ export const legacyYGOProAuth = async (ctx: Context) => {
if (!user) {
return ctx.throw(404);
}
user.cleanSensitiveData();
ctx.body = { user };
};
......
import { Column, CreateDateColumn, Entity, PrimaryColumn, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm';
import { ColumnTypes } from 'typeorm/metadata/types/ColumnTypes';
import { URL } from 'url';
@Entity('users')
export class User {
@PrimaryGeneratedColumn(ColumnTypes.INTEGER)
@PrimaryGeneratedColumn({type: 'int4'})
id: number;
@Column(ColumnTypes.STRING, { unique: true, nullable: false })
@Column('varchar', { length: 255, unique: true, nullable: false })
username: string;
@Column(ColumnTypes.STRING, { nullable: true })
@Column('varchar', { length: 255, nullable: true })
name?: string;
@Column(ColumnTypes.STRING, { nullable: false })
@Column('varchar', { length: 255, nullable: false })
email: string;
@Column(ColumnTypes.STRING, { nullable: false })
@Column('varchar', { length: 255, nullable: false })
password_hash: string;
@Column(ColumnTypes.STRING, { nullable: false })
@Column('varchar', { length: 255, nullable: false })
salt: string;
@Column(ColumnTypes.BOOLEAN, { nullable: false })
@Column('boolean', { nullable: false })
active: boolean;
@Column(ColumnTypes.BOOLEAN, { nullable: false })
@Column('boolean', { nullable: false })
admin: boolean;
@Column(ColumnTypes.STRING, { nullable: true })
@Column('varchar', { length: 255, nullable: true })
avatar?: string;
@Column(ColumnTypes.STRING, { nullable: false })
@Column('varchar', { length: 255, nullable: false })
locale: string;
@Column(ColumnTypes.STRING, { nullable: false })
@Column('varchar', { length: 255, nullable: false })
registration_ip_address: string;
@Column(ColumnTypes.STRING, { nullable: false })
@Column('varchar', { length: 255, nullable: false })
ip_address: string;
@CreateDateColumn({ nullable: false })
created_at: Date;
......@@ -57,6 +56,15 @@ export class User {
return 'https://cdn01.moecube.com/accounts/default_avatar.jpg';
}
}
cleanSensitiveData() {
// this.email = '_masked';
this.password_hash = '_masked';
this.salt = '_masked';
this.registration_ip_address = '_masked';
this.ip_address = '_masked';
return this;
}
}
interface UserCreate {
......@@ -74,13 +82,13 @@ interface UserCreate {
@Entity('tokens')
export class Token {
@PrimaryColumn(ColumnTypes.STRING)
@PrimaryColumn('varchar', { length: 255 })
key: string;
@Column(ColumnTypes.STRING, { nullable: false })
@Column('varchar', { length: 255, nullable: false })
user_id: number;
@Column(ColumnTypes.STRING, { nullable: false })
@Column('varchar', { length: 255, nullable: false })
type: string;
@Column(ColumnTypes.STRING, { nullable: false })
@Column('varchar', { length: 255, nullable: false })
data: string;
constructor(props: Token) {
......@@ -112,13 +120,13 @@ export interface SignUp {
@Entity('username_change_history')
export class UserNameChangeHistory {
@PrimaryGeneratedColumn(ColumnTypes.INTEGER)
@PrimaryGeneratedColumn({type: 'int4'})
id: number;
@Column(ColumnTypes.INTEGER)
@Column('int4')
userid: number;
@Column(ColumnTypes.STRING)
@Column('varchar', { length: 255 })
old_username: string;
@Column(ColumnTypes.STRING)
@Column('varchar', { length: 255 })
new_username: string;
@UpdateDateColumn()
change_time: Date;
......@@ -130,4 +138,4 @@ export class UserNameChangeHistory {
this.change_time = new Date();
}
}
\ No newline at end of file
}
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment