updated filelist storage so userid is not used directly

This commit is contained in:
Danny Coates 2019-02-26 13:53:11 -08:00
parent d55f0247de
commit 4cb6646cce
No known key found for this signature in database
GPG Key ID: 4C442633C62E00CB
4 changed files with 24 additions and 14 deletions

View File

@ -371,9 +371,9 @@ export function downloadFile(id, keychain, onprogress) {
}; };
} }
export async function getFileList(bearerToken) { export async function getFileList(bearerToken, kid) {
const headers = new Headers({ Authorization: `Bearer ${bearerToken}` }); const headers = new Headers({ Authorization: `Bearer ${bearerToken}` });
const response = await fetch(getApiUrl('/api/filelist'), { headers }); const response = await fetch(getApiUrl(`/api/filelist/${kid}`), { headers });
if (response.ok) { if (response.ok) {
const encrypted = await response.blob(); const encrypted = await response.blob();
return encrypted; return encrypted;
@ -381,9 +381,9 @@ export async function getFileList(bearerToken) {
throw new Error(response.status); throw new Error(response.status);
} }
export async function setFileList(bearerToken, data) { export async function setFileList(bearerToken, kid, data) {
const headers = new Headers({ Authorization: `Bearer ${bearerToken}` }); const headers = new Headers({ Authorization: `Bearer ${bearerToken}` });
const response = await fetch(getApiUrl('/api/filelist'), { const response = await fetch(getApiUrl(`/api/filelist/${kid}`), {
headers, headers,
method: 'POST', method: 'POST',
body: data body: data

View File

@ -159,10 +159,13 @@ export default class User {
return this.storage.merge(); return this.storage.merge();
} }
let list = []; let list = [];
const key = b64ToArray(this.info.fileListKey);
const sha = await crypto.subtle.digest('SHA-256', key);
const kid = arrayToB64(new Uint8Array(sha)).substring(0, 16);
try { try {
const encrypted = await getFileList(this.bearerToken); const encrypted = await getFileList(this.bearerToken, kid);
const decrypted = await streamToArrayBuffer( const decrypted = await streamToArrayBuffer(
decryptStream(blobStream(encrypted), b64ToArray(this.info.fileListKey)) decryptStream(blobStream(encrypted), key)
); );
list = JSON.parse(textDecoder.decode(decrypted)); list = JSON.parse(textDecoder.decode(decrypted));
} catch (e) { } catch (e) {
@ -180,9 +183,9 @@ export default class User {
textEncoder.encode(JSON.stringify(this.storage.files)) textEncoder.encode(JSON.stringify(this.storage.files))
]); ]);
const encrypted = await streamToArrayBuffer( const encrypted = await streamToArrayBuffer(
encryptStream(blobStream(blob), b64ToArray(this.info.fileListKey)) encryptStream(blobStream(blob), key)
); );
await setFileList(this.bearerToken, encrypted); await setFileList(this.bearerToken, kid, encrypted);
} catch (e) { } catch (e) {
// //
} }

View File

@ -1,9 +1,14 @@
const crypto = require('crypto');
const config = require('../config'); const config = require('../config');
const storage = require('../storage'); const storage = require('../storage');
const Limiter = require('../limiter'); const Limiter = require('../limiter');
function id(user) { function id(user, kid) {
return `filelist-${user}`; const sha = crypto.createHash('sha256');
sha.update(user);
sha.update(kid);
const hash = sha.digest('hex');
return `filelist-${hash}`;
} }
module.exports = { module.exports = {
@ -11,8 +16,9 @@ module.exports = {
if (!req.user) { if (!req.user) {
return res.sendStatus(401); return res.sendStatus(401);
} }
const kid = req.params.id;
try { try {
const fileId = id(req.user); const fileId = id(req.user, kid);
const contentLength = await storage.length(fileId); const contentLength = await storage.length(fileId);
const fileStream = await storage.get(fileId); const fileStream = await storage.get(fileId);
res.writeHead(200, { res.writeHead(200, {
@ -29,11 +35,12 @@ module.exports = {
if (!req.user) { if (!req.user) {
return res.sendStatus(401); return res.sendStatus(401);
} }
const kid = req.params.id;
try { try {
const limiter = new Limiter(1024 * 1024 * 10); const limiter = new Limiter(1024 * 1024 * 10);
const fileStream = req.pipe(limiter); const fileStream = req.pipe(limiter);
await storage.set( await storage.set(
id(req.user), id(req.user, kid),
fileStream, fileStream,
null, null,
config.max_expire_seconds config.max_expire_seconds

View File

@ -88,8 +88,8 @@ module.exports = function(app) {
); );
app.get(`/api/exists/:id${ID_REGEX}`, require('./exists')); app.get(`/api/exists/:id${ID_REGEX}`, require('./exists'));
app.get(`/api/metadata/:id${ID_REGEX}`, auth.hmac, require('./metadata')); app.get(`/api/metadata/:id${ID_REGEX}`, auth.hmac, require('./metadata'));
app.get('/api/filelist', auth.fxa, filelist.get); app.get('/api/filelist/:id(\\w{16})', auth.fxa, filelist.get);
app.post('/api/filelist', auth.fxa, filelist.post); app.post('/api/filelist/:id(\\w{16})', auth.fxa, filelist.post);
app.post('/api/upload', auth.fxa, require('./upload')); app.post('/api/upload', auth.fxa, require('./upload'));
app.post(`/api/delete/:id${ID_REGEX}`, auth.owner, require('./delete')); app.post(`/api/delete/:id${ID_REGEX}`, auth.owner, require('./delete'));
app.post(`/api/password/:id${ID_REGEX}`, auth.owner, require('./password')); app.post(`/api/password/:id${ID_REGEX}`, auth.owner, require('./password'));