From a021e4431cd67f85e8d74efc13cfcf41ba46ec3b Mon Sep 17 00:00:00 2001 From: CounterFire2023 <136581895+CounterFire2023@users.noreply.github.com> Date: Thu, 10 Aug 2023 13:43:27 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9token=E7=94=9F=E6=88=90?= =?UTF-8?q?=E6=96=B9=E6=B3=95=EF=BC=8C=E5=8A=A0=E5=85=A5version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.development | 2 +- src/api.server.ts | 1 + src/controllers/apple.controller.ts | 7 ++- src/controllers/facebook.controller.ts | 7 ++- src/controllers/google.controller.ts | 59 ++++++++++++++++++++++++++ src/controllers/mail.controller.ts | 7 ++- src/controllers/main.controllers.ts | 53 +++-------------------- src/controllers/tiktok.controller.ts | 7 ++- src/controllers/wallet.controller.ts | 5 +++ src/modules/Account.ts | 3 ++ 10 files changed, 99 insertions(+), 52 deletions(-) create mode 100644 src/controllers/google.controller.ts diff --git a/.env.development b/.env.development index 7808afc..a4f1302 100644 --- a/.env.development +++ b/.env.development @@ -8,7 +8,7 @@ API_TOKEN_EXPIRESIN=1d GOOGLE_OAUTH_CLIENT="53206975661-asnf3qe4bg29p8h981pgf099osvrjbme.apps.googleusercontent.com" GOOGLE_OAUTH_CLIENT2="53206975661-ih3r0ubph3rqejdq97b029difbrk2bqj.apps.googleusercontent.com" GOOGLE_OAUTH_CLIENT_IOS="53206975661-qan0rnefniegjv53ohild375pv0p7ekd.apps.googleusercontent.com" -DB_MAIN=mongodb://localhost/wallet-development +DB_MAIN=mongodb://192.168.100.22/wallet-development EMAIL_VERIFY_URL="https://wallet.cebggame.com" EMAIL_SERVER='http://127.0.0.1:3087' diff --git a/src/api.server.ts b/src/api.server.ts index 9a90725..fced374 100644 --- a/src/api.server.ts +++ b/src/api.server.ts @@ -43,6 +43,7 @@ export class ApiServer { expiresIn: config.api.token_expiresIn, }) if (process.env.NODE_ENV !== 'production') { + mongoose.set('debug', true) this.server.register(require('@fastify/cors'), {}) } } diff --git a/src/controllers/apple.controller.ts b/src/controllers/apple.controller.ts index 74b01a1..d14f75e 100644 --- a/src/controllers/apple.controller.ts +++ b/src/controllers/apple.controller.ts @@ -34,7 +34,12 @@ class AppleController extends BaseController { if (payload.name) data.nickname = payload.name if (payload.picture) data.avatar = payload.picture let user = await Account.insertOrUpdate({ plat: PlatEnum.APPLE, openId }, data) - const ztoken = await res.jwtSign({ id: user.id, openid: openId, plat: PlatEnum.APPLE }) + const ztoken = await res.jwtSign({ + id: user.id, + openid: user.openId, + version: user.accountVersion || 0, + plat: PlatEnum.APPLE, + }) return { token: ztoken } } diff --git a/src/controllers/facebook.controller.ts b/src/controllers/facebook.controller.ts index ef33375..232a67a 100644 --- a/src/controllers/facebook.controller.ts +++ b/src/controllers/facebook.controller.ts @@ -39,7 +39,12 @@ class FacebookController extends BaseController { if (infoRes['name']) user.nickname = infoRes['name'] if (infoRes['email']) user.email = infoRes['email'] let account = await Account.insertOrUpdate({ plat: PlatEnum.FACEBOOK, openId }, user) - const ztoken = await res.jwtSign({ id: account.id, openid: openId, plat: PlatEnum.FACEBOOK }) + const ztoken = await res.jwtSign({ + id: account.id, + openid: user.openId, + version: user.accountVersion || 0, + plat: PlatEnum.FACEBOOK, + }) return { token: ztoken } } } diff --git a/src/controllers/google.controller.ts b/src/controllers/google.controller.ts new file mode 100644 index 0000000..4ace310 --- /dev/null +++ b/src/controllers/google.controller.ts @@ -0,0 +1,59 @@ +import BaseController, { ROLE_ANON } from 'common/base.controller' +import { ZError } from 'common/ZError' +import { role, router } from 'decorators/router' + +import { OAuth2Client } from 'google-auth-library' +import { Account, PlatEnum } from 'modules/Account' +import { customAlphabet } from 'nanoid' + +const nanoid = customAlphabet('1234567890abcdef', 10) +const GOOGLE_OAUTH_ISS = 'https://accounts.google.com' +const GOOGLE_OAUTH_ISS1 = 'accounts.google.com' +const IOS_TEST = '53206975661-0d6q9pqljn84n9l63gm0to1ulap9cbk4.apps.googleusercontent.com' + +class GoogleController extends BaseController { + @role(ROLE_ANON) + @router('post /wallet/login/google') + async checkGoogleJwt(req, res) { + const { token } = req.params + const CLIENT_ID = process.env.GOOGLE_OAUTH_CLIENT + const CLIENT_ID2 = process.env.GOOGLE_OAUTH_CLIENT2 + const CLIENT_ID_IOS = process.env.GOOGLE_OAUTH_CLIENT_IOS + const client = new OAuth2Client(CLIENT_ID) + const ticket = await client.verifyIdToken({ + idToken: token, + audience: [CLIENT_ID, CLIENT_ID2, CLIENT_ID_IOS, IOS_TEST], // Specify the CLIENT_ID of the app that accesses the backend + // Or, if multiple clients access the backend: + //[CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3] + }) + const payload = ticket.getPayload() + if (!(payload.iss === GOOGLE_OAUTH_ISS || payload.iss === GOOGLE_OAUTH_ISS1)) { + throw new ZError(10, 'id token error') + } + if ( + payload.aud !== CLIENT_ID && + payload.aud !== CLIENT_ID2 && + payload.aud !== CLIENT_ID_IOS && + payload.aud !== IOS_TEST + ) { + throw new ZError(11, 'client id mismatch') + } + const openId = payload.sub + let data: any = {} + if (payload.email) data.email = payload.email + if (process.env.NODE_ENV !== 'development') { + if (payload.email_verified !== undefined) data.emailVerified = payload.email_verified + } + if (payload.locale) data.locale = payload.locale + if (payload.name) data.nickname = payload.name + if (payload.picture) data.avatar = payload.picture + let user = await Account.insertOrUpdate({ plat: PlatEnum.GOOGLE, openId }, data) + const ztoken = await res.jwtSign({ + id: user.id, + openid: user.openId, + version: user.accountVersion || 0, + plat: PlatEnum.GOOGLE, + }) + return { token: ztoken } + } +} diff --git a/src/controllers/mail.controller.ts b/src/controllers/mail.controller.ts index f835b72..e4c4a4e 100644 --- a/src/controllers/mail.controller.ts +++ b/src/controllers/mail.controller.ts @@ -37,7 +37,12 @@ class MailController extends BaseController { if (!record.verifyPassword(password)) { throw new ZError(13, 'password error') } - const token = await res.jwtSign({ id: record.id, openid: record.openId, plat: PlatEnum.EMAIL }) + const token = await res.jwtSign({ + id: record.id, + openid: record.openId, + version: record.accountVersion || 0, + plat: PlatEnum.EMAIL, + }) return { token: token } } diff --git a/src/controllers/main.controllers.ts b/src/controllers/main.controllers.ts index aece449..60ddf6c 100644 --- a/src/controllers/main.controllers.ts +++ b/src/controllers/main.controllers.ts @@ -1,15 +1,7 @@ import BaseController, { ROLE_ANON } from 'common/base.controller' import { ZError } from 'common/ZError' import { role, router } from 'decorators/router' - -import { OAuth2Client } from 'google-auth-library' -import { Account, PlatEnum } from 'modules/Account' -import { customAlphabet } from 'nanoid' - -const nanoid = customAlphabet('1234567890abcdef', 10) -const GOOGLE_OAUTH_ISS = 'https://accounts.google.com' -const GOOGLE_OAUTH_ISS1 = 'accounts.google.com' -const IOS_TEST = '53206975661-0d6q9pqljn84n9l63gm0to1ulap9cbk4.apps.googleusercontent.com' +import { Account } from 'modules/Account' class MainController extends BaseController { @role(ROLE_ANON) @@ -19,43 +11,10 @@ class MainController extends BaseController { return {} } - @role(ROLE_ANON) - @router('post /wallet/login/google') - async checkGoogleJwt(req, res) { - const { token } = req.params - const CLIENT_ID = process.env.GOOGLE_OAUTH_CLIENT - const CLIENT_ID2 = process.env.GOOGLE_OAUTH_CLIENT2 - const CLIENT_ID_IOS = process.env.GOOGLE_OAUTH_CLIENT_IOS - const client = new OAuth2Client(CLIENT_ID) - const ticket = await client.verifyIdToken({ - idToken: token, - audience: [CLIENT_ID, CLIENT_ID2, CLIENT_ID_IOS, IOS_TEST], // Specify the CLIENT_ID of the app that accesses the backend - // Or, if multiple clients access the backend: - //[CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3] - }) - const payload = ticket.getPayload() - if (!(payload.iss === GOOGLE_OAUTH_ISS || payload.iss === GOOGLE_OAUTH_ISS1)) { - throw new ZError(10, 'id token error') - } - if ( - payload.aud !== CLIENT_ID && - payload.aud !== CLIENT_ID2 && - payload.aud !== CLIENT_ID_IOS && - payload.aud !== IOS_TEST - ) { - throw new ZError(11, 'client id mismatch') - } - const openId = payload.sub - let data: any = {} - if (payload.email) data.email = payload.email - if (process.env.NODE_ENV !== 'development') { - if (payload.email_verified !== undefined) data.emailVerified = payload.email_verified - } - if (payload.locale) data.locale = payload.locale - if (payload.name) data.nickname = payload.name - if (payload.picture) data.avatar = payload.picture - let user = await Account.insertOrUpdate({ plat: PlatEnum.GOOGLE, openId }, data) - const ztoken = await res.jwtSign({ id: user.id, openid: openId, plat: PlatEnum.GOOGLE }) - return { token: ztoken } + @router('post /wallet/account/reset') + async resetAccount(req, res) { + const user = req.user + await user.updateOne({ $inc: { accountVersion: 1 } }) + return {} } } diff --git a/src/controllers/tiktok.controller.ts b/src/controllers/tiktok.controller.ts index 8f8af06..d3f6619 100644 --- a/src/controllers/tiktok.controller.ts +++ b/src/controllers/tiktok.controller.ts @@ -23,7 +23,12 @@ class TiktokController extends BaseController { user.refreshTokenExpire = now + result.data['refresh_expires_in'] - EXPIRE_REDUCE_SECOND user.scope = result.data['scope'] let account = await Account.insertOrUpdate({ plat: PlatEnum.TIKTOK, openId }, user) - const ztoken = await res.jwtSign({ id: account.id, openid: openId, plat: PlatEnum.TIKTOK }) + const ztoken = await res.jwtSign({ + id: account.id, + openid: user.openId, + version: user.accountVersion || 0, + plat: PlatEnum.TIKTOK, + }) return { token: ztoken } } @router('post /wallet/tiktok/accesstoken') diff --git a/src/controllers/wallet.controller.ts b/src/controllers/wallet.controller.ts index c069da3..52bc36b 100644 --- a/src/controllers/wallet.controller.ts +++ b/src/controllers/wallet.controller.ts @@ -66,6 +66,11 @@ class WalletController extends BaseController { return {} } + @router('post /wallet/rest') + async resetWalletInfo(req, res) { + return {} + } + @router('post /wallet/collection') async uploadUserCollection(req, res) { let user = req.user diff --git a/src/modules/Account.ts b/src/modules/Account.ts index de979ac..94a1d8a 100644 --- a/src/modules/Account.ts +++ b/src/modules/Account.ts @@ -102,6 +102,9 @@ class AccountClass extends BaseModule { @prop() public emailVerifyTime?: number + // 用于标识该账号是否已经重置过 + @prop({ default: 0 }) + public accountVersion: number public static async findByEmail(this: ReturnModelType, email) { return this.findOne({ email, plat: PlatEnum.EMAIL }).exec()