Skip to content

Commit

Permalink
asd
Browse files Browse the repository at this point in the history
  • Loading branch information
dbarrosop committed Feb 9, 2024
1 parent c99d24b commit a845783
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 1 deletion.
7 changes: 7 additions & 0 deletions src/gql/user-authenticators.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,10 @@ mutation updateUserSecurityKey($id: uuid!, $counter: bigint!) {
id
}
}

mutation deleteUserSecurityKey($id: uuid!, $userId: uuid!) {
deleteAuthUserSecurityKeys(where: {id: {_eq: $id}, userId: {_eq: $userId}}) {
affected_rows
}
}

36 changes: 35 additions & 1 deletion src/routes/user/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { bodyValidator } from '@/validation';
import { authenticationGate } from '@/middleware/auth';

import { userMFAHandler, userMfaSchema } from './mfa';
import { userHandler } from './user';
import { userHandler, deleteUserHandler } from './user';
import { userPasswordHandler, userPasswordSchema } from './password';
import {
userPasswordResetHandler,
Expand All @@ -26,6 +26,8 @@ import {
addSecurityKeyHandler,
addSecurityKeyVerifyHandler,
userVerifyAddSecurityKeySchema,
userDeleteSecurityKeySchema,
deleteSecurityKeyVerifyHandler,
} from './webauthn';

const router = Router();
Expand All @@ -44,6 +46,21 @@ router.get(
aw(userHandler),
);

/**
* POST /user/delete
* @summary Deletes the authenticated user
* @return {string} 200 - The user has been successfully deleted - application/json
* @return {InvalidRequestError} 400 - The payload is invalid - application/json
* @return {UnauthenticatedUserError} 401 - User is not authenticated - application/json
* @security BearerAuth
* @tags User management
*/
router.post(
'/user/delete',
authenticationGate(true),
aw(deleteUserHandler),
);

/**
* POST /user/password/reset
* @summary Send an email asking the user to reset their password
Expand Down Expand Up @@ -188,5 +205,22 @@ router.post(
aw(addSecurityKeyVerifyHandler)
);

/**
* POST /user/webauthn/delete
* @summary Deletes a webauthn security key
* @param {DeleteSecurityKeySchema} request.body.required
* @return {string} 200 - The security key has been successfully deleted - application/json
* @return {InvalidRequestError} 400 - The payload is invalid - application/json
* @return {UnauthenticatedUserError} 401 - User is not authenticated - application/json
* @security BearerAuth
* @tags User management
*/
router.post(
'/user/webauthn/delete',
bodyValidator(userDeleteSecurityKeySchema),
authenticationGate(true),
aw(deleteSecurityKeyVerifyHandler)
);

const userRouter = router;
export { userRouter };
20 changes: 20 additions & 0 deletions src/routes/user/user.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { RequestHandler } from 'express';
import { ReasonPhrases } from 'http-status-codes';

import { sendError } from '@/errors';

import { getUser } from '@/utils';
import { gqlSdk } from '../../utils/gql-sdk';

export const userHandler: RequestHandler = async (
req,
Expand All @@ -14,3 +18,19 @@ export const userHandler: RequestHandler = async (
...user,
});
};

export const deleteUserHandler: RequestHandler = async (
req,
res
): Promise<unknown> => {
const { userId } = req.auth as RequestAuth;


try {
await gqlSdk.deleteUser({ userId });
} catch (e) {
return sendError(res, 'invalid-request');
}

return res.json(ReasonPhrases.OK);
};
28 changes: 28 additions & 0 deletions src/routes/user/webauthn.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { RequestHandler } from 'express';
import { ReasonPhrases } from 'http-status-codes';

import { generateRegistrationOptions } from '@simplewebauthn/server';
import {
Expand Down Expand Up @@ -103,3 +104,30 @@ export const addSecurityKeyVerifyHandler: RequestHandler<
return sendUnspecifiedError(res, e);
}
};

export type DeleteSecurityKeyRequestBody = {
id: string;
};

export const userDeleteSecurityKeySchema =
Joi.object<DeleteSecurityKeyRequestBody>({
id: Joi.string().required(),
}).meta({ className: 'DeleteSecurityKeySchema' });

export const deleteSecurityKeyVerifyHandler: RequestHandler<
{},
{},
DeleteSecurityKeyRequestBody
> = async (req, res) => {

const resp = await gqlSdk.deleteUserSecurityKey({
id: req.body.id,
userId: req.auth?.userId,
});

if (!resp.deleteAuthUserSecurityKeys?.affected_rows) {
return sendError(res, 'invalid-request');
}

return res.json(ReasonPhrases.OK);
};
18 changes: 18 additions & 0 deletions src/utils/__generated__/graphql-request.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit a845783

Please sign in to comment.