summaryrefslogtreecommitdiff
path: root/api
diff options
context:
space:
mode:
Diffstat (limited to 'api')
-rw-r--r--api/auth/_verifyRegistrationResponse.ts15
-rw-r--r--api/auth/registration.ts14
-rw-r--r--api/db/_deleteCurrentChallenge.ts15
-rw-r--r--api/db/_deleteUser.ts18
-rw-r--r--api/db/_deleteUserAuthenticators.ts16
5 files changed, 66 insertions, 12 deletions
diff --git a/api/auth/_verifyRegistrationResponse.ts b/api/auth/_verifyRegistrationResponse.ts
index 66af079..350bf0b 100644
--- a/api/auth/_verifyRegistrationResponse.ts
+++ b/api/auth/_verifyRegistrationResponse.ts
@@ -4,8 +4,6 @@ import { type RegistrationResponseJSON } from '@simplewebauthn/server/script/dep
import { verifyRegistrationResponse as innerVerifyRegistrationResponse } from '@simplewebauthn/server';
import RELYING_PARTY from './_relyingParty';
-import addAuthenticator from '../db/_addAuthenticator';
-import addUser from '../db/_addUser';
import env from '../_env';
/**
@@ -14,14 +12,14 @@ import env from '../_env';
* matches the expected challenge, which should be the most recent challenge
* to be associated with the given user.
*
- * If verification is successful, saves the new user and their new
- * authenticator to the database.
+ * If verification is successful, returns the authenticator object. Otherwise,
+ * returns null.
*/
export default async function verifyRegistrationResponse(
newUser: User,
expectedChallenge: string,
registrationResponse: RegistrationResponseJSON,
-): Promise<boolean> {
+): Promise<Authenticator | null> {
const verification = await innerVerifyRegistrationResponse({
response: registrationResponse,
expectedChallenge,
@@ -34,7 +32,7 @@ export default async function verifyRegistrationResponse(
});
if (!verification.verified || !verification.registrationInfo) {
- return false;
+ return null;
}
const authenticator: Authenticator = {
@@ -55,8 +53,5 @@ export default async function verifyRegistrationResponse(
transports: verification.registrationInfo['transports'] ?? [],
};
- await addUser(newUser);
- await addAuthenticator(authenticator);
-
- return true;
+ return authenticator;
}
diff --git a/api/auth/registration.ts b/api/auth/registration.ts
index d318d83..9f1c377 100644
--- a/api/auth/registration.ts
+++ b/api/auth/registration.ts
@@ -6,6 +6,9 @@ import verifyRegistrationResponse from './_verifyRegistrationResponse';
import getUser from '../db/_getUser';
import getCurrentChallenge from '../db/_getCurrentChallenge';
import setCurrentChallenge from '../db/_setCurrentChallenge';
+import { getFirstQueryParam } from '../_getFirstQueryParam';
+import addUser from 'db/_addUser';
+import addAuthenticator from 'db/_addAuthenticator';
/**
* # registration
@@ -152,8 +155,15 @@ async function handlePost(request: VercelRequest): Promise<(r: VercelResponse) =
);
}
- const isValid = await verifyRegistrationResponse(newUser, expectedChallenge, registrationResponse);
+ const authenticator = await verifyRegistrationResponse(newUser, expectedChallenge, registrationResponse);
+ const isVerified = !!authenticator;
+
+ if (isVerified) {
+ await addUser(newUser);
+ await addAuthenticator(authenticator);
+ }
+
return (response) => void (
- response.status(200).send(isValid ? 'true' : 'false')
+ response.status(200).send(isVerified ? 'true' : 'false')
);
}
diff --git a/api/db/_deleteCurrentChallenge.ts b/api/db/_deleteCurrentChallenge.ts
new file mode 100644
index 0000000..1f597bc
--- /dev/null
+++ b/api/db/_deleteCurrentChallenge.ts
@@ -0,0 +1,15 @@
+import { sql } from '@vercel/postgres';
+import { CURRENT_CHALLENGES } from './_tables';
+
+export default async function deleteCurrentChallenge(userId: string) {
+ const query = `
+ DELETE FROM ${CURRENT_CHALLENGES.name}
+ WHERE ${CURRENT_CHALLENGES.fields.userId} = '${userId}'
+ `;
+
+ try {
+ await sql.query(query);
+ } catch (err) {
+ throw new Error(`Failed to delete current challenge for user with ID ${userId} in database. Query was ${query.replace(/\s+/g, ' ')}. ${err}`);
+ }
+}
diff --git a/api/db/_deleteUser.ts b/api/db/_deleteUser.ts
new file mode 100644
index 0000000..c926800
--- /dev/null
+++ b/api/db/_deleteUser.ts
@@ -0,0 +1,18 @@
+import type User from '../types/User';
+
+import { sql } from '@vercel/postgres';
+import { USERS } from './_tables';
+
+export default async function deleteUser(id: User['id']) {
+ const query = `
+ DELETE FROM ${USERS.name}
+ WHERE ${USERS.fields.id} = '${id}',
+ ;
+ `;
+
+ try {
+ await sql.query(query);
+ } catch (err) {
+ throw new Error(`Failed to delete user from database with ID: ${id}. Query was ${query.replace(/\s+/g, ' ')}. ${err}`);
+ }
+}
diff --git a/api/db/_deleteUserAuthenticators.ts b/api/db/_deleteUserAuthenticators.ts
new file mode 100644
index 0000000..32f4ea5
--- /dev/null
+++ b/api/db/_deleteUserAuthenticators.ts
@@ -0,0 +1,16 @@
+import { sql } from '@vercel/postgres';
+import { AUTHENTICATORS } from './_tables';
+import User from '../types/User';
+
+export default async function deleteUserAuthenticators(userId: User['id']) {
+ const query = `
+ DELETE FROM ${AUTHENTICATORS.name}
+ WHERE ${AUTHENTICATORS.fields.id} = '${id}';
+ `;
+
+ try {
+ await sql.query(query);
+ } catch (err) {
+ throw new Error(`Failed to delete authenticators for user with ID ${userId} from database. Query was ${query.replace(/\s+/g, ' ')}. ${err}`);
+ }
+}