Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * What's wrong here and how can this be improved?
- */
- // Basically a lot of the code inside `updateUserPassword` can be moved out of the function body into other smaller functions.
- // This would make the code easier to understand and it would enable a potentially better unit test coverage (unit test many small functions rather than one big function alone)
- async function updateUserPassword(data, ctx) {
- const user = await getUser({ userId: data.userId }, ctx);
- // the following 2 lines would be more efficient if placed outside the function
- const userRoles = config.get("userRoles");
- const allowedClientRoles = config.get("allowedClientRoles");
- const sameTenants = utils.compareClientTenantIdWithUserTenantId(
- data.tenantId,
- ctx
- );
- // logTenantError can be moved outside of this function with a parametrized `ctx`, like `const logTenantError = (ctx) => { ... }
- // 403 and "access_denied" are better stored in application constants rather than used as literal values
- const logTenantError = () => {
- const message = "Access denied";
- log.request(message, ctx, ERROR);
- throw error.create(message, 403, "access_denied");
- };
- // can be moved out with parametrized `sameTenants`
- const checkTenant = () =>
- fp.cond([
- [fp.isEqual(true), fp.noop],
- [fp.isEqual(false), logTenantError]
- ])(sameTenants);
- // can be moved out ...
- const checkUserPermission = () =>
- fp.cond([
- [fp.isEqual(true), fp.noop],
- [fp.isEqual(false), checkTenant]
- ])(userRoles.includes(user.role));
- // same here
- const logClientError = () => {
- const message = "Access denied";
- log.request(message, ctx, ERROR);
- throw error.create(message, 403, "access_denied");
- };
- fp.cond([
- [fp.isEqual(true), checkUserPermission],
- [fp.isEqual(false), logClientError]
- ])(allowedClientRoles.includes(await getClientRole(ctx)));
- const queryResult = await db.query(
- `FOR user IN users FILTER password == @password AND userId == @userId and tenantId == @tenantId`,
- {
- tenantId: data.tenantId,
- userId: data.userId,
- password: decrypt(data.password)
- }
- );
- if (!queryResult.hasNext()) {
- throw error.create("User not found", 404, "user_not_found");
- }
- // `rev` is an unused param in both following logger functions
- const logErrorRevokeTokens = (rev, message, context) => {
- log.request(message, context, ERROR);
- };
- const logSuccessRevokeTokens = (rev, message, context) =>{
- log.request(message, context, INFO);
- };
- const { tenantId, userId } = data;
- const { revoked, message } = await utils.revokeTokensOfUser(
- tenantId,
- userId,
- ctx
- );
- // This will probably always branch on TRUE, because fp.cond evaluates each parameter (revoked, message and ctx) for each predicate.
- // Even if `revoked` is `false`, `message` and/or `ctx` are very likely to always evaluate to a "truthy" value when coerced into booleans.
- fp.cond([
- [fp.isEqual(true), logSuccessRevokeTokens],
- [fp.isEqual(false), logErrorRevokeTokens]
- ])(revoked, message, ctx);
- return;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement