diff --git a/packages/admin/src/index.ts b/packages/admin/src/index.ts index d8a9e456f..d0718c56c 100644 --- a/packages/admin/src/index.ts +++ b/packages/admin/src/index.ts @@ -74,7 +74,8 @@ export default class AdminModule extends IConduitAdmin { private _sdkRoutes: ConduitRoute[] = [ adminRoutes.getLoginRoute(), adminRoutes.getCreateAdminRoute(), - adminRoutes.getAdminUsersRoute(), + adminRoutes.getAdminRoute(), + adminRoutes.getAdminsRoute(), adminRoutes.deleteAdminUserRoute(), adminRoutes.changePasswordRoute(), adminRoutes.getReadyRoute(), diff --git a/packages/admin/src/middleware/Auth.middleware.ts b/packages/admin/src/middleware/Auth.middleware.ts index 368833df2..60598a640 100644 --- a/packages/admin/src/middleware/Auth.middleware.ts +++ b/packages/admin/src/middleware/Auth.middleware.ts @@ -77,7 +77,7 @@ export function getAuthMiddleware(grpcSdk: ConduitGrpcSdk, conduit: ConduitCommo Admin.getInstance() .findOne({ _id: id }) - .then((admin: any) => { + .then(admin => { if (isNil(admin)) { return res.status(401).json({ error: 'No such user exists' }); } diff --git a/packages/admin/src/models/Admin.schema.ts b/packages/admin/src/models/Admin.schema.ts index ce45ba739..2f054c3a6 100644 --- a/packages/admin/src/models/Admin.schema.ts +++ b/packages/admin/src/models/Admin.schema.ts @@ -1,6 +1,6 @@ import { ConduitActiveSchema, DatabaseProvider, TYPE } from '@conduitplatform/grpc-sdk'; -export const schema = { +const schema = { _id: TYPE.ObjectId, username: { type: TYPE.String, @@ -9,6 +9,7 @@ export const schema = { password: { type: TYPE.String, required: true, + select: false, }, hasTwoFA: { type: TYPE.Boolean, diff --git a/packages/admin/src/models/index.ts b/packages/admin/src/models/index.ts index e71391184..1156ec753 100644 --- a/packages/admin/src/models/index.ts +++ b/packages/admin/src/models/index.ts @@ -1,2 +1,2 @@ -export { Admin } from './Admin.schema'; +export * from './Admin.schema'; export * from './AdminTwoFactorSecret'; diff --git a/packages/admin/src/routes/ChangePassword.route.ts b/packages/admin/src/routes/ChangePassword.route.ts index 65cdd3a97..33cc6037f 100644 --- a/packages/admin/src/routes/ChangePassword.route.ts +++ b/packages/admin/src/routes/ChangePassword.route.ts @@ -24,9 +24,15 @@ export function changePasswordRoute() { new ConduitRouteReturnDefinition('ChangePassword', { message: ConduitString.Required, }), - async (params: ConduitRouteParameters) => { - const { oldPassword, newPassword } = params.params!; - const admin = params.context!.admin; + async (req: ConduitRouteParameters) => { + const { oldPassword, newPassword } = req.params!; + const admin = await Admin.getInstance().findOne( + { _id: req.context!.admin }, + 'password', + ); + if (!admin) { + throw ConduitError.notFound('Authenticated admin no longer exists'); + } if (isNil(oldPassword) || isNil(newPassword)) { throw new ConduitError( diff --git a/packages/admin/src/routes/ChangeUsersPassword.route.ts b/packages/admin/src/routes/ChangeUsersPassword.route.ts index 7fb8e2ab8..88167d2ba 100644 --- a/packages/admin/src/routes/ChangeUsersPassword.route.ts +++ b/packages/admin/src/routes/ChangeUsersPassword.route.ts @@ -26,9 +26,9 @@ export function changeUsersPasswordRoute() { new ConduitRouteReturnDefinition('ChangePassword', { message: ConduitString.Required, }), - async (params: ConduitRouteParameters) => { - const { adminId, newPassword } = params.params!; - const loggedInAdmin = params.context!.admin; + async (req: ConduitRouteParameters) => { + const { adminId, newPassword } = req.params!; + const loggedInAdmin = req.context!.admin; if (!loggedInAdmin.isSuperAdmin) { throw new ConduitError( diff --git a/packages/admin/src/routes/CreateAdmin.route.ts b/packages/admin/src/routes/CreateAdmin.route.ts index 44b437986..e97976012 100644 --- a/packages/admin/src/routes/CreateAdmin.route.ts +++ b/packages/admin/src/routes/CreateAdmin.route.ts @@ -24,9 +24,9 @@ export function getCreateAdminRoute() { new ConduitRouteReturnDefinition('Create', { message: ConduitString.Required, }), - async (params: ConduitRouteParameters) => { - const { username, password } = params.params!; - const loggedInAdmin = params.context!.admin; + async (req: ConduitRouteParameters) => { + const { username, password } = req.params!; + const loggedInAdmin = req.context!.admin; if (isNil(username) || isNil(password)) { throw new ConduitError( diff --git a/packages/admin/src/routes/DeleteAdminUser.route.ts b/packages/admin/src/routes/DeleteAdminUser.route.ts index 45b6de584..834fed609 100644 --- a/packages/admin/src/routes/DeleteAdminUser.route.ts +++ b/packages/admin/src/routes/DeleteAdminUser.route.ts @@ -21,9 +21,9 @@ export function deleteAdminUserRoute() { new ConduitRouteReturnDefinition('DeleteAdminUser', { message: ConduitString.Required, }), - async (params: ConduitRouteParameters) => { - const { id } = params.params!; - const loggedInAdmin = params.context!.admin; + async (req: ConduitRouteParameters) => { + const { id } = req.params!; + const loggedInAdmin = req.context!.admin; if (isNil(id)) { throw new ConduitError('INVALID_ARGUMENTS', 400, 'Id must be provided'); } diff --git a/packages/admin/src/routes/GetAdmin.route.ts b/packages/admin/src/routes/GetAdmin.route.ts new file mode 100644 index 000000000..1c42f3646 --- /dev/null +++ b/packages/admin/src/routes/GetAdmin.route.ts @@ -0,0 +1,33 @@ +import { + ConduitRouteActions, + ConduitRouteParameters, + ConduitString, + ConduitError, +} from '@conduitplatform/grpc-sdk'; +import { Admin } from '../models'; +import { ConduitRoute, ConduitRouteReturnDefinition } from '@conduitplatform/hermes'; + +export function getAdminRoute() { + return new ConduitRoute( + { + path: '/admins/:id', + action: ConduitRouteActions.GET, + description: `Returns an admin user. Passing 'me' as 'id' returns the authenticated admin performing the request`, + urlParams: { + id: ConduitString.Required, + }, + }, + new ConduitRouteReturnDefinition('GetAdmin', Admin.name), + async (req: ConduitRouteParameters) => { + const adminId = req.params!.id; + const admin: Admin = + adminId === 'me' + ? req.context!.admin + : await Admin.getInstance().findOne({ _id: adminId }); + if (!admin) { + throw ConduitError.notFound('Admin does not exist'); + } + return admin; + }, + ); +} diff --git a/packages/admin/src/routes/GetAdminUsers.route.ts b/packages/admin/src/routes/GetAdmins.route.ts similarity index 76% rename from packages/admin/src/routes/GetAdminUsers.route.ts rename to packages/admin/src/routes/GetAdmins.route.ts index 5fec0b559..22b8e28b9 100644 --- a/packages/admin/src/routes/GetAdminUsers.route.ts +++ b/packages/admin/src/routes/GetAdmins.route.ts @@ -6,9 +6,8 @@ import { } from '@conduitplatform/grpc-sdk'; import { Admin } from '../models'; import { ConduitRoute, ConduitRouteReturnDefinition } from '@conduitplatform/hermes'; -import { schema as AdminSchema } from '../models/Admin.schema'; -export function getAdminUsersRoute() { +export function getAdminsRoute() { return new ConduitRoute( { path: '/admins', @@ -21,13 +20,13 @@ export function getAdminUsersRoute() { }, }, new ConduitRouteReturnDefinition('GetAdminUsers', { - admins: [AdminSchema], + admins: [Admin.name], count: ConduitNumber.Required, }), - async (params: ConduitRouteParameters) => { - const skip = params.params!.skip ?? 0; - const limit = params.params!.limit ?? 25; - const sort = params.params!.sort; + async (req: ConduitRouteParameters) => { + const skip = req.params!.skip ?? 0; + const limit = req.params!.limit ?? 25; + const sort = req.params!.sort; const adminsPromise = Admin.getInstance().findMany( {}, '-password', diff --git a/packages/admin/src/routes/Login.route.ts b/packages/admin/src/routes/Login.route.ts index c29a3b918..bacad0499 100644 --- a/packages/admin/src/routes/Login.route.ts +++ b/packages/admin/src/routes/Login.route.ts @@ -26,8 +26,8 @@ export function getLoginRoute() { new ConduitRouteReturnDefinition('Login', { token: ConduitString.Required, }), - async (params: ConduitRouteParameters) => { - const { username, password } = params.params!; + async (req: ConduitRouteParameters) => { + const { username, password } = req.params!; if (isNil(username) || isNil(password)) { throw new ConduitError( 'INVALID_ARGUMENTS', @@ -36,7 +36,7 @@ export function getLoginRoute() { ); } - const admin = await Admin.getInstance().findOne({ username }); + const admin = await Admin.getInstance().findOne({ username }, 'password'); if (isNil(admin)) { throw new ConduitError('UNAUTHORIZED', 401, 'Invalid username/password'); } diff --git a/packages/admin/src/routes/ToggleTwoFa.route.ts b/packages/admin/src/routes/ToggleTwoFa.route.ts index fcd7843ea..5b30a0094 100644 --- a/packages/admin/src/routes/ToggleTwoFa.route.ts +++ b/packages/admin/src/routes/ToggleTwoFa.route.ts @@ -23,10 +23,10 @@ export function toggleTwoFaRoute() { new ConduitRouteReturnDefinition('ToggleTwoFaResponse', { message: ConduitString.Required, }), - async (params: ConduitRouteParameters) => { - const { enableTwoFa } = params.params!; - const admin = params.context!.admin; - const context = params.context!; + async (req: ConduitRouteParameters) => { + const { enableTwoFa } = req.params!; + const admin = req.context!.admin; + const context = req.context!; if (isNil(context) || isNil(admin)) { throw new GrpcError(status.UNAUTHENTICATED, 'Unauthorized'); diff --git a/packages/admin/src/routes/VerifyQrCode.route.ts b/packages/admin/src/routes/VerifyQrCode.route.ts index 7251b539a..8e0fc9c9d 100644 --- a/packages/admin/src/routes/VerifyQrCode.route.ts +++ b/packages/admin/src/routes/VerifyQrCode.route.ts @@ -22,11 +22,11 @@ export function verifyQrCodeRoute() { new ConduitRouteReturnDefinition('VerifyQRCodeResponse', { message: ConduitString.Required, }), - async (params: ConduitRouteParameters) => { - const admin = params.context!.admin; - const context = params.context!; + async (req: ConduitRouteParameters) => { + const admin = req.context!.admin; + const context = req.context!; - const { code } = params.params!; + const { code } = req.params!; if (isNil(context) || isEmpty(context)) { throw new GrpcError(status.UNAUTHENTICATED, 'User unauthenticated'); diff --git a/packages/admin/src/routes/VerifyTwoFa.route.ts b/packages/admin/src/routes/VerifyTwoFa.route.ts index ffec009f0..70a103db1 100644 --- a/packages/admin/src/routes/VerifyTwoFa.route.ts +++ b/packages/admin/src/routes/VerifyTwoFa.route.ts @@ -18,9 +18,9 @@ export function verifyTwoFaRoute() { new ConduitRouteReturnDefinition('VerifyTwoFaResponse', { token: ConduitString.Required, }), - async (params: ConduitRouteParameters) => { - const { code } = params.params!; - const admin = params.context!.admin; + async (req: ConduitRouteParameters) => { + const { code } = req.params!; + const admin = req.context!.admin; return await verify2Fa(admin, code); }, ); diff --git a/packages/admin/src/routes/index.ts b/packages/admin/src/routes/index.ts index b498965c3..c646f29a9 100644 --- a/packages/admin/src/routes/index.ts +++ b/packages/admin/src/routes/index.ts @@ -1,6 +1,7 @@ export * from './Login.route'; export * from './CreateAdmin.route'; -export * from './GetAdminUsers.route'; +export * from './GetAdmin.route'; +export * from './GetAdmins.route'; export * from './DeleteAdminUser.route'; export * from './ChangePassword.route'; export * from './Ready';