From 3b4cff15b0797cb90ada542c8484eb5edcdfe489 Mon Sep 17 00:00:00 2001 From: YANG QIA <2013xile@gmail.com> Date: Sat, 16 Sep 2023 13:55:29 +0800 Subject: [PATCH] fix(auth): change password issue of basic auth (#2662) --- .../core/client/src/user/ChangePassword.tsx | 2 +- .../resourcer/src/__tests__/resourcer.test.ts | 32 ++++++++++++ packages/core/resourcer/src/resource.ts | 16 +++++- .../src/server/__tests__/actions.test.ts | 31 +++++++++++ .../plugin-auth/src/server/basic-auth.ts | 8 ++- .../plugin-auth/src/server/plugin.ts | 4 +- .../plugin-auth/src/swagger/index.ts | 52 +++++++++++++++++++ 7 files changed, 140 insertions(+), 5 deletions(-) diff --git a/packages/core/client/src/user/ChangePassword.tsx b/packages/core/client/src/user/ChangePassword.tsx index 774804861..c3ac598c6 100644 --- a/packages/core/client/src/user/ChangePassword.tsx +++ b/packages/core/client/src/user/ChangePassword.tsx @@ -26,7 +26,7 @@ const useSaveCurrentUserValues = () => { return { async run() { await form.submit(); - await api.resource('users').changePassword({ + await api.resource('auth').changePassword({ values: form.values, }); await form.reset(); diff --git a/packages/core/resourcer/src/__tests__/resourcer.test.ts b/packages/core/resourcer/src/__tests__/resourcer.test.ts index b5faa34e8..0f3c17b72 100644 --- a/packages/core/resourcer/src/__tests__/resourcer.test.ts +++ b/packages/core/resourcer/src/__tests__/resourcer.test.ts @@ -713,4 +713,36 @@ describe('resourcer', () => { expect(context.arr).toEqual([2, 9, 10, 3]); }); + + it('add action', async () => { + const resourcer = new Resourcer(); + resourcer.define({ + name: 'test', + middleware: require('./middlewares/demo1'), + actions: { + list: { + handler: require('./actions/demo1'), + }, + }, + }); + resourcer.getResource('test').addAction('new', async function (ctx, next) { + ctx.arr.push(100); + await next(); + ctx.arr.push(101); + }); + + const context = { + arr: [], + }; + + await resourcer.execute( + { + resource: 'test', + action: 'new', + }, + context, + ); + + expect(context.arr).toEqual([2, 100, 101, 3]); + }); }); diff --git a/packages/core/resourcer/src/resource.ts b/packages/core/resourcer/src/resource.ts index 20888f2d7..6a5021ade 100644 --- a/packages/core/resourcer/src/resource.ts +++ b/packages/core/resourcer/src/resource.ts @@ -1,7 +1,7 @@ import _ from 'lodash'; import Action, { ActionName, ActionType } from './action'; import Middleware, { MiddlewareType } from './middleware'; -import { Resourcer } from './resourcer'; +import { HandlerType, Resourcer } from './resourcer'; export type ResourceType = 'single' | 'hasOne' | 'hasMany' | 'belongsTo' | 'belongsToMany'; @@ -88,6 +88,20 @@ export class Resource { return this.except; } + addAction(name: ActionName, handler: HandlerType) { + if (this.except.includes(name)) { + throw new Error(`${name} action is not allowed`); + } + if (this.actions.has(name)) { + throw new Error(`${name} action already exists`); + } + const action = new Action(handler); + action.setName(name); + action.setResource(this); + action.middlewares.unshift(...this.middlewares); + this.actions.set(name, action); + } + getAction(action: ActionName) { if (this.except.includes(action)) { throw new Error(`${action} action is not allowed`); diff --git a/packages/plugins/@nocobase/plugin-auth/src/server/__tests__/actions.test.ts b/packages/plugins/@nocobase/plugin-auth/src/server/__tests__/actions.test.ts index 0fee16066..72000e665 100644 --- a/packages/plugins/@nocobase/plugin-auth/src/server/__tests__/actions.test.ts +++ b/packages/plugins/@nocobase/plugin-auth/src/server/__tests__/actions.test.ts @@ -168,5 +168,36 @@ describe('actions', () => { const token = data.token; expect(token).toBeDefined(); }); + + it('should change password', async () => { + // Create a user without email + const userRepo = db.getRepository('users'); + const user = await userRepo.create({ + values: { + username: 'test', + password: '12345', + }, + }); + const res = await agent.login(user).post('/auth:changePassword').set({ 'X-Authenticator': 'basic' }).send({ + oldPassword: '12345', + newPassword: '123456', + confirmPassword: '123456', + }); + expect(res.statusCode).toEqual(200); + + // Create a user without username + const user1 = await userRepo.create({ + values: { + username: 'test2', + password: '12345', + }, + }); + const res2 = await agent.login(user1).post('/auth:changePassword').set({ 'X-Authenticator': 'basic' }).send({ + oldPassword: '12345', + newPassword: '123456', + confirmPassword: '123456', + }); + expect(res2.statusCode).toEqual(200); + }); }); }); diff --git a/packages/plugins/@nocobase/plugin-auth/src/server/basic-auth.ts b/packages/plugins/@nocobase/plugin-auth/src/server/basic-auth.ts index 40c745368..7ac3b2329 100644 --- a/packages/plugins/@nocobase/plugin-auth/src/server/basic-auth.ts +++ b/packages/plugins/@nocobase/plugin-auth/src/server/basic-auth.ts @@ -124,9 +124,15 @@ export class BasicAuth extends BaseAuth { if (!currentUser) { ctx.throw(401); } + let key: string; + if (currentUser.username) { + key = 'username'; + } else { + key = 'email'; + } const user = await this.userRepository.findOne({ where: { - email: currentUser.email, + [key]: currentUser[key], }, }); const pwd = this.userCollection.getField('password'); diff --git a/packages/plugins/@nocobase/plugin-auth/src/server/plugin.ts b/packages/plugins/@nocobase/plugin-auth/src/server/plugin.ts index 276a6c78f..53b02aa48 100644 --- a/packages/plugins/@nocobase/plugin-auth/src/server/plugin.ts +++ b/packages/plugins/@nocobase/plugin-auth/src/server/plugin.ts @@ -50,8 +50,8 @@ export class AuthPlugin extends Plugin { title: 'Password', }); // Register actions - Object.entries(authActions).forEach(([action, handler]) => - this.app.resourcer.registerAction(`auth:${action}`, handler), + Object.entries(authActions).forEach( + ([action, handler]) => this.app.resourcer.getResource('auth')?.addAction(action, handler), ); Object.entries(authenticatorsActions).forEach(([action, handler]) => this.app.resourcer.registerAction(`authenticators:${action}`, handler), diff --git a/packages/plugins/@nocobase/plugin-auth/src/swagger/index.ts b/packages/plugins/@nocobase/plugin-auth/src/swagger/index.ts index 849b39e9d..27ab5cd84 100644 --- a/packages/plugins/@nocobase/plugin-auth/src/swagger/index.ts +++ b/packages/plugins/@nocobase/plugin-auth/src/swagger/index.ts @@ -318,6 +318,58 @@ export default { }, }, }, + '/auth:changePassword': { + post: { + description: 'Change password', + tags: ['Basic auth'], + security: [], + requestBody: { + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + oldPassword: { + type: 'string', + description: '旧密码', + }, + newPassword: { + type: 'string', + description: '新密码', + }, + confirmPassword: { + type: 'string', + description: '确认密码', + }, + }, + }, + }, + }, + }, + responses: { + 200: { + description: 'ok', + content: { + 'application/json': { + schema: { + $ref: '#/components/schemas/user', + }, + }, + }, + }, + 401: { + description: 'Unauthorized', + content: { + 'application/json': { + schema: { + $ref: '#/components/schemas/error', + }, + }, + }, + }, + }, + }, + }, 'authenticators:listTypes': { get: { description: 'List authenticator types',