retry setPassword on first nonce failure. fixes #664

This commit is contained in:
Danny Coates 2017-12-08 09:45:00 -08:00
parent b96d2949f7
commit 81f3347981
No known key found for this signature in database
GPG Key ID: 4C442633C62E00CB
2 changed files with 40 additions and 30 deletions

View File

@ -12,6 +12,33 @@ async function getAuthHeader(authKey, nonce) {
return `send-v1 ${arrayToB64(new Uint8Array(sig))}`; return `send-v1 ${arrayToB64(new Uint8Array(sig))}`;
} }
async function sendPassword(file, authKey, rawAuth) {
const authHeader = await getAuthHeader(authKey, file.nonce);
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
return resolve(xhr.response);
}
if (xhr.status === 401) {
const nonce = xhr.getResponseHeader('WWW-Authenticate').split(' ')[1];
file.nonce = nonce;
}
reject(new Error(xhr.status));
}
};
xhr.onerror = () => reject(new Error(0));
xhr.ontimeout = () => reject(new Error(0));
xhr.open('post', `/api/password/${file.id}`);
xhr.setRequestHeader('Authorization', authHeader);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.responseType = 'json';
xhr.timeout = 2000;
xhr.send(JSON.stringify({ auth: arrayToB64(new Uint8Array(rawAuth)) }));
});
}
export default class FileSender extends Nanobus { export default class FileSender extends Nanobus {
constructor(file) { constructor(file) {
super('FileSender'); super('FileSender');
@ -259,7 +286,6 @@ export default class FileSender extends Nanobus {
true, true,
['sign'] ['sign']
); );
const authHeader = await getAuthHeader(authKey, file.nonce);
const pwdKey = await window.crypto.subtle.importKey( const pwdKey = await window.crypto.subtle.importKey(
'raw', 'raw',
encoder.encode(password), encoder.encode(password),
@ -283,30 +309,14 @@ export default class FileSender extends Nanobus {
['sign'] ['sign']
); );
const rawAuth = await window.crypto.subtle.exportKey('raw', newAuthKey); const rawAuth = await window.crypto.subtle.exportKey('raw', newAuthKey);
return new Promise((resolve, reject) => { try {
const xhr = new XMLHttpRequest(); await sendPassword(file, authKey, rawAuth);
xhr.onreadystatechange = () => { } catch (e) {
if (xhr.readyState === XMLHttpRequest.DONE) { if (e.message === '401' && file.nonce !== e.nonce) {
if (xhr.status === 200) { await sendPassword(file, authKey, rawAuth);
return resolve(xhr.response); } else {
} throw e;
if (xhr.status === 401) { }
const nonce = xhr }
.getResponseHeader('WWW-Authenticate')
.split(' ')[1];
file.nonce = nonce;
}
reject(new Error(xhr.status));
}
};
xhr.onerror = () => reject(new Error(0));
xhr.ontimeout = () => reject(new Error(0));
xhr.open('post', `/api/password/${file.id}`);
xhr.setRequestHeader('Authorization', authHeader);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.responseType = 'json';
xhr.timeout = 2000;
xhr.send(JSON.stringify({ auth: arrayToB64(new Uint8Array(rawAuth)) }));
});
} }
} }

View File

@ -24,12 +24,12 @@ module.exports = async function(req, res) {
res.set('WWW-Authenticate', `send-v1 ${meta.nonce}`); res.set('WWW-Authenticate', `send-v1 ${meta.nonce}`);
return res.sendStatus(401); return res.sendStatus(401);
} }
const nonce = crypto.randomBytes(16).toString('base64');
storage.setField(id, 'nonce', nonce);
res.set('WWW-Authenticate', `send-v1 ${nonce}`);
} catch (e) { } catch (e) {
res.sendStatus(404); return res.sendStatus(404);
} }
const nonce = crypto.randomBytes(16).toString('base64');
storage.setField(id, 'nonce', nonce);
res.set('WWW-Authenticate', `send-v1 ${nonce}`);
storage.setField(id, 'auth', req.body.auth); storage.setField(id, 'auth', req.body.auth);
storage.setField(id, 'pwd', 1); storage.setField(id, 'pwd', 1);
res.sendStatus(200); res.sendStatus(200);