'use strict'; var Keypairs = require('@root/keypairs'); var PocketId = module.exports; var request = require('./request.js'); var keyJson = window.localStorage.getItem('private.jwk.json'); PocketId.signIdToken = async function (idToken) { var pair = await Keypairs.parseOrGenerate({ key: keyJson }); var jwt = await Keypairs.signJwt({ jwk: pair.private, iss: window.location.protocol + '//' + window.location.hostname, exp: '15m', claims: { contact: ['google:' + idToken] } }); return jwt; }; PocketId.auth = {}; PocketId.auth.meta = async function ({ email }) { var loc = window.location; var body = await request({ method: 'GET', url: loc.protocol + '//' + loc.hostname + '/api/authn/meta?contact=' + 'mailto:' + email }); return body; }; PocketId.auth.verify = async function ({ scheme, email }) { if (!scheme) { scheme = 'mailto:'; } var loc = window.location; var body = await request({ method: 'GET', url: loc.protocol + '//' + loc.hostname + '/api/authn/verify?contact=' + scheme + email }); return body; }; PocketId.auth.consume = async function ({ email = '', receipt = '', secret = '', count = 0 }) { var loc = window.location; var resp = await request({ method: 'GET', url: loc.protocol + '//' + loc.hostname + '/api/authn/consume?contact=' + (email ? 'mailto:' + email : '') + '&receipt=' + receipt + '&secret=' + secret }); if (resp.body.success) { // There should be a token here // (or the pubkey should have been given beforehand) return resp.body; } if (resp.body.error) { // TODO special errors are hard failures } if (count > 600) { throw new Error('abandoned login'); } return timeout(5000).then(function () { console.log('check otp again'); return PocketId.auth.consume({ email, secret, receipt, count: count || 0 }); }); }; async function timeout(ms) { return new Promise(function (resolve) { setTimeout(resolve, ms); }); } var textEncoder = new TextEncoder(); PocketId.genKey = async function ({ email }) { // Ideally we'd use PBKDF2 or better but... web standards... // TODO put a random salt var emailU8 = textEncoder.encode(email); var salt = await crypto.subtle.digest('SHA-256', emailU8); var u8 = textEncoder.encode(answer); var hash = await crypto.subtle.digest('SHA-256', u8); };