Skip to content

Commit 7fbea21

Browse files
committed
Fix: close #26
Finally I figured out a backward compatible solution of password verification
1 parent f17f260 commit 7fbea21

4 files changed

Lines changed: 24 additions & 6 deletions

File tree

packages/backend/src/services/auth.service.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Role } from '@constants/enums';
55
import { JwtPayload } from '@interfaces/jwt.interface';
66
import { CandidatesService } from '@services/candidates.service';
77
import { UsersService } from '@services/users.service';
8-
import { verify } from '@utils/scrypt';
8+
import { backwardCompatibleVerify, verify } from '@utils/scrypt';
99

1010
@Injectable()
1111
export class AuthService {
@@ -20,7 +20,11 @@ export class AuthService {
2020
const user = await this.usersService.findIdentityByPhone(phone);
2121
if (user) {
2222
const { password: { hash, salt }, id } = user;
23-
if (await verify(hash, salt, password)) {
23+
if (Buffer.from(salt, 'base64').length !== 16 && await verify(hash, salt, password)) {
24+
return id;
25+
} else if (await backwardCompatibleVerify(Buffer.from(hash, 'base64').toString(), salt, password)) {
26+
user.password = await this.usersService.hashPassword(password);
27+
await user.save();
2428
return id;
2529
}
2630
}

packages/backend/src/services/users.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export class UsersService extends BasicCRUDService<UserEntity> {
1717
super(repository);
1818
}
1919

20-
findIdentityByPhone(phone: string): Promise<Pick<UserEntity, 'id' | 'password'> | undefined> {
20+
findIdentityByPhone(phone: string) {
2121
return this.findOne(
2222
{
2323
phone,

packages/backend/src/utils/migrate.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,11 @@ export const migrate = async (app: INestApplication) => {
8888
await recruitmentsService.clear();
8989
await usersService.clear();
9090
await Promise.all(users.map(async (
91-
{ weChatID, avatar, gender, group, isAdmin, isCaptain, joinTime, mail, phone, username },
91+
{ weChatID, avatar, gender, group, isAdmin, isCaptain, joinTime, mail, phone, username, password },
9292
) => {
93+
if (password) {
94+
password.hash = Buffer.from(password.hash).toString('base64');
95+
}
9396
joinTime = joinTime === '2018年3月' ? '2018S' // two lucky guys
9497
: joinTime === '2017日常招新' ? '2017A' // this kind of recruitments are not supported yet
9598
: joinTime.replaceAll('年', '');
@@ -105,7 +108,7 @@ export const migrate = async (app: INestApplication) => {
105108
avatar: avatar || undefined,
106109
isAdmin,
107110
isCaptain,
108-
password: await hash(randomBytes(512).toString('hex')),
111+
password: password || await hash(randomBytes(512).toString('hex')),
109112
});
110113
}));
111114
await Promise.all(recruitments.map(async (

packages/backend/src/utils/scrypt.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ interface ScryptResult {
66
}
77

88
export const hash = (password: string) => new Promise<ScryptResult>((resolve, reject) => {
9-
const salt = randomBytes(16);
9+
const salt = randomBytes(32);
1010
scrypt(password, salt, 64, (err, derivedKey) => {
1111
if (err) {
1212
return reject(err);
@@ -18,6 +18,17 @@ export const hash = (password: string) => new Promise<ScryptResult>((resolve, re
1818
});
1919
});
2020

21+
// TODO: deprecate it in v4
22+
export const backwardCompatibleVerify = (hash: string, salt: string, password: string) =>
23+
new Promise<boolean>((resolve, reject) => {
24+
scrypt(password, salt, 64, (err, derivedKey) => {
25+
if (err) {
26+
return reject(err);
27+
}
28+
return resolve(derivedKey.toString() === hash);
29+
});
30+
});
31+
2132
export const verify = (hash: string, salt: string, password: string) => new Promise<boolean>((resolve, reject) => {
2233
scrypt(password, Buffer.from(salt, 'base64'), 64, (err, derivedKey) => {
2334
if (err) {

0 commit comments

Comments
 (0)