diff --git a/src/api/routes/auth/login.ts b/src/api/routes/auth/login.ts
index a2100333..d2384337 100644
--- a/src/api/routes/auth/login.ts
+++ b/src/api/routes/auth/login.ts
@@ -139,7 +139,9 @@ router.post(
ticket: ticket,
mfa: true,
sms: false, // TODO
- token: null,
+ totp: true,
+ backup: true,
+ user_id: user.id,
});
}
@@ -172,7 +174,9 @@ router.post(
ticket: ticket,
mfa: true,
sms: false, // TODO
- token: null,
+ totp: true,
+ backup: true,
+ user_id: user.id,
webauthn: challenge,
});
}
@@ -202,7 +206,13 @@ router.post(
// Discord header is just the user id as string, which is not possible with npm-jsonwebtoken package
// https://user-images.githubusercontent.com/6506416/81051916-dd8c9900-8ec2-11ea-8794-daf12d6f31f0.png
- res.json({ token, settings: { ...user.settings, index: undefined } });
+ res.json({
+ token,
+ settings: {
+ locale: user.settings.locale,
+ theme: user.settings.theme,
+ },
+ });
},
);
@@ -211,15 +221,12 @@ router.post(
* @argument { login: "email@gmail.com", password: "cleartextpassword", undelete: false, captcha_key: null, login_source: null, gift_code_sku_id: null, }
* MFA required:
- * @returns {"token": null, "mfa": true, "sms": true, "ticket": "SOME TICKET JWT TOKEN"}
-
- * WebAuthn MFA required:
- * @returns {"token": null, "mfa": true, "webauthn": true, "sms": true, "ticket": "SOME TICKET JWT TOKEN"}
+ * @returns {"mfa": true, "sms": boolean, "totp": boolean, "backup": true, "ticket": "SOME TICKET JWT TOKEN", "user_id": "USER ID", "webauthn": "WEBAUTHN DATA or null"}
* Captcha required:
* @returns {"captcha_key": ["captcha-required"], "captcha_sitekey": null, "captcha_service": "recaptcha"}
* Sucess:
- * @returns {"token": "USERTOKEN", "settings": {"locale": "en", "theme": "dark"}}
+ * @returns {"token": "USERTOKEN", "user_id": "USER ID", "settings": {"locale": "en-US", "theme": "dark"}}
*/
diff --git a/src/api/routes/auth/mfa/totp.ts b/src/api/routes/auth/mfa/totp.ts
index 4df408f9..20ecd7a1 100644
--- a/src/api/routes/auth/mfa/totp.ts
+++ b/src/api/routes/auth/mfa/totp.ts
@@ -73,7 +73,10 @@ router.post(
return res.json({
token: await generateToken(user.id),
- settings: { ...user.settings, index: undefined },
+ settings: {
+ locale: user.settings.locale,
+ theme: user.settings.theme,
+ },
});
},
);
diff --git a/src/api/routes/auth/mfa/webauthn.ts b/src/api/routes/auth/mfa/webauthn.ts
index b58d2944..687fdcd8 100644
--- a/src/api/routes/auth/mfa/webauthn.ts
+++ b/src/api/routes/auth/mfa/webauthn.ts
@@ -114,7 +114,10 @@ router.post(
return res.json({
token: await generateToken(user.id),
- user_settings: user.settings,
+ user_settings: {
+ locale: user.settings.locale,
+ theme: user.settings.theme,
+ },
});
},
);
diff --git a/src/api/routes/users/@me/mfa/totp/enable.ts b/src/api/routes/users/@me/mfa/totp/enable.ts
index 19836e4d..5471e0b5 100644
--- a/src/api/routes/users/@me/mfa/totp/enable.ts
+++ b/src/api/routes/users/@me/mfa/totp/enable.ts
@@ -18,6 +18,7 @@
import { route } from "@spacebar/api";
import {
+ AuthenticatorType,
TotpEnableSchema,
User,
generateMfaBackupCodes,
@@ -74,7 +75,14 @@ router.post(
await Promise.all(backup_codes.map((x) => x.save()));
await User.update(
{ id: req.user_id },
- { mfa_enabled: true, totp_secret: body.secret },
+ {
+ mfa_enabled: true,
+ totp_secret: body.secret,
+ authenticator_types: [
+ ...user.authenticator_types,
+ AuthenticatorType.TOTP,
+ ],
+ },
);
res.send({
diff --git a/src/api/routes/users/@me/mfa/webauthn/credentials/index.ts b/src/api/routes/users/@me/mfa/webauthn/credentials/index.ts
index f383ffb7..c8e5b67a 100644
--- a/src/api/routes/users/@me/mfa/webauthn/credentials/index.ts
+++ b/src/api/routes/users/@me/mfa/webauthn/credentials/index.ts
@@ -18,9 +18,12 @@
import { route } from "@spacebar/api";
import {
+ AuthenticatorType,
+ BackupCode,
CreateWebAuthnCredentialSchema,
DiscordApiErrors,
FieldErrors,
+ generateMfaBackupCodes,
GenerateWebAuthnCredentialsSchema,
generateWebAuthnTicket,
SecurityKey,
@@ -193,12 +196,41 @@ router.post(
await Promise.all([
securityKey.save(),
- User.update({ id: req.user_id }, { webauthn_enabled: true }),
+ User.update(
+ { id: req.user_id },
+ {
+ webauthn_enabled: true,
+ authenticator_types: [
+ ...user.authenticator_types,
+ AuthenticatorType.WEBAUTHN,
+ ],
+ },
+ ),
]);
+ // try and get the users existing backup codes
+ let backup_codes = await BackupCode.find({
+ where: {
+ user: {
+ id: req.user_id,
+ },
+ },
+ });
+
+ // if there arent any, create them
+ if (!backup_codes.length) {
+ backup_codes = generateMfaBackupCodes(req.user_id);
+ await Promise.all(backup_codes.map((x) => x.save()));
+ }
+
return res.json({
name,
id: securityKey.id,
+ type: AuthenticatorType.WEBAUTHN, // I think thats what this is?
+ backup_codes: backup_codes.map((x) => ({
+ ...x,
+ expired: undefined,
+ })),
});
} else {
throw DiscordApiErrors.INVALID_AUTHENTICATION_TOKEN;
|