summaryrefslogtreecommitdiff
path: root/src/server/api/endpoints/i/2fa/getkeys.ts
diff options
context:
space:
mode:
authorMary <Ipadlover8322@gmail.com>2019-07-03 07:18:07 -0400
committersyuilo <Syuilotan@yahoo.co.jp>2019-07-03 20:18:07 +0900
commitfd94b817abd8fa628586746eed3a1f61b4a2b3d8 (patch)
tree53eccf1b923f9b29f73ec6651b361b1682af3247 /src/server/api/endpoints/i/2fa/getkeys.ts
parentResolve #5072 (diff)
downloadmisskey-fd94b817abd8fa628586746eed3a1f61b4a2b3d8.tar.gz
misskey-fd94b817abd8fa628586746eed3a1f61b4a2b3d8.tar.bz2
misskey-fd94b817abd8fa628586746eed3a1f61b4a2b3d8.zip
Implement Webauthn ๐ŸŽ‰ (#5088)
* Implement Webauthn :tada: * Share hexifyAB * Move hr inside template and add AttestationChallenges janitor daemon * Apply suggestions from code review Co-Authored-By: Acid Chicken (็กซ้…ธ้ถ) <root@acid-chicken.com> * Add newline at the end of file * Fix stray newline in promise chain * Ignore var in try{}catch(){} block Co-Authored-By: Acid Chicken (็กซ้…ธ้ถ) <root@acid-chicken.com> * Add missing comma * Add missing semicolon * Support more attestation formats * add support for more key types and linter pass * Refactor * Refactor * credentialId --> id * Fix * Improve readability * Add indexes * fixes for credentialId->id * Avoid changing store state * Fix syntax error and code style * Remove unused import * Refactor of getkey API * Create 1561706992953-webauthn.ts * Update ja-JP.yml * Add type annotations * Fix code style * Specify depedency version * Fix code style * Fix janitor daemon and login requesting 2FA regardless of status
Diffstat (limited to 'src/server/api/endpoints/i/2fa/getkeys.ts')
-rw-r--r--src/server/api/endpoints/i/2fa/getkeys.ts67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/server/api/endpoints/i/2fa/getkeys.ts b/src/server/api/endpoints/i/2fa/getkeys.ts
new file mode 100644
index 0000000000..bb1585d795
--- /dev/null
+++ b/src/server/api/endpoints/i/2fa/getkeys.ts
@@ -0,0 +1,67 @@
+import $ from 'cafy';
+import * as bcrypt from 'bcryptjs';
+import * as crypto from 'crypto';
+import define from '../../../define';
+import { UserProfiles, UserSecurityKeys, AttestationChallenges } from '../../../../../models';
+import { ensure } from '../../../../../prelude/ensure';
+import { promisify } from 'util';
+import { hash } from '../../../2fa';
+import { genId } from '../../../../../misc/gen-id';
+
+export const meta = {
+ requireCredential: true,
+
+ secure: true,
+
+ params: {
+ password: {
+ validator: $.str
+ }
+ }
+};
+
+const randomBytes = promisify(crypto.randomBytes);
+
+export default define(meta, async (ps, user) => {
+ const profile = await UserProfiles.findOne(user.id).then(ensure);
+
+ // Compare password
+ const same = await bcrypt.compare(ps.password, profile.password!);
+
+ if (!same) {
+ throw new Error('incorrect password');
+ }
+
+ const keys = await UserSecurityKeys.find({
+ userId: user.id
+ });
+
+ if (keys.length === 0) {
+ throw new Error('no keys found');
+ }
+
+ // 32 byte challenge
+ const entropy = await randomBytes(32);
+ const challenge = entropy.toString('base64')
+ .replace(/=/g, '')
+ .replace(/\+/g, '-')
+ .replace(/\//g, '_');
+
+ const challengeId = genId();
+
+ await AttestationChallenges.save({
+ userId: user.id,
+ id: challengeId,
+ challenge: hash(Buffer.from(challenge, 'utf-8')).toString('hex'),
+ createdAt: new Date(),
+ registrationChallenge: false
+ });
+
+ return {
+ challenge,
+ challengeId,
+ securityKeys: keys.map(key => ({
+ id: key.id
+ }))
+ };
+});