diff options
| author | Mary <Ipadlover8322@gmail.com> | 2019-07-03 07:18:07 -0400 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2019-07-03 20:18:07 +0900 |
| commit | fd94b817abd8fa628586746eed3a1f61b4a2b3d8 (patch) | |
| tree | 53eccf1b923f9b29f73ec6651b361b1682af3247 /src/server/api/endpoints/i/2fa/getkeys.ts | |
| parent | Resolve #5072 (diff) | |
| download | misskey-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.ts | 67 |
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 + })) + }; +}); |