Skip to content

Commit

Permalink
Throw a recoverable error if public keys cannot be fetched. (#146)
Browse files Browse the repository at this point in the history
  • Loading branch information
philipp-classen authored Jan 15, 2025
1 parent 1d029c6 commit a319666
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 21 deletions.
23 changes: 17 additions & 6 deletions communication/src/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
* in the code (e.g. configuration errors, incorrect use of the API).
*/
class ExtendableError extends Error {
constructor(message) {
super(message);
constructor(message, options) {
super(message, options);
this.name = this.constructor.name;
if (typeof Error.captureStackTrace === 'function') {
Error.captureStackTrace(this, this.constructor);
Expand Down Expand Up @@ -55,8 +55,8 @@ class ExtendableError extends Error {
* retried at a later point, or replaced by updated messages.
*/
class RecoverableError extends ExtendableError {
constructor(message) {
super(message);
constructor(message, options) {
super(message, options);
this.isRecoverableError = true;
this.isPermanentError = false;
}
Expand All @@ -70,15 +70,26 @@ class RecoverableError extends ExtendableError {
* trying to send it again will again trigger the identical error.
*/
class PermanentError extends ExtendableError {
constructor(message) {
super(message);
constructor(message, options) {
super(message, options);
this.isRecoverableError = false;
this.isPermanentError = true;
}
}

/**
* The message size exceeded the limit of 32K.
*/
export class TooBigMsgError extends PermanentError {}

export class TransportError extends RecoverableError {}
export class ProtocolError extends PermanentError {}
export class InvalidMessageError extends PermanentError {}
export class ClockOutOfSync extends RecoverableError {}

/**
* Thrown when the client failed to fetch public keys. Without
* current keys, it cannot setup the end-to-end encryption
* needed to communicate with the server.
*/
export class FailedToFetchPublicKeys extends RecoverableError {}
42 changes: 27 additions & 15 deletions communication/src/server-public-key-accessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import logger from './logger.js';
import { getTimeAsYYYYMMDD } from './timestamps.js';
import { fromBase64 } from './encoding.js';
import { FailedToFetchPublicKeys } from './errors.js';

function isYYYYMMDD(date) {
return typeof date === 'string' && /^[0-9]{8}$/.test(date);
Expand Down Expand Up @@ -72,21 +73,7 @@ export default class ServerPublicKeyAccessor {

// not found on disk or outdated -> fetch from server
if (!knownKeys) {
const url = `${this.collectorUrl}/config?fields=pubKeys`;
logger.info('Fetching new server public keys from', url);
const response = await fetch(url, {
method: 'GET',
credentials: 'omit',
redirect: 'manual',
});
if (!response.ok) {
throw new Error(
`Failed to get config (${response.statusText}) from url=${url}`,
);
}
const { pubKeys } = await response.json();
logger.info('Fetched server public keys:', pubKeys);

const pubKeys = await this._fetchPublicKeys();
const allKeys = Object.keys(pubKeys)
.filter(isYYYYMMDD)
.map((date) => [date, fromBase64(pubKeys[date])]);
Expand All @@ -104,6 +91,31 @@ export default class ServerPublicKeyAccessor {
this._knownKeys = knownKeys;
}

async _fetchPublicKeys() {
const url = `${this.collectorUrl}/config?fields=pubKeys`;
logger.info('Fetching new server public keys from', url);
try {
const response = await fetch(url, {
method: 'GET',
credentials: 'omit',
redirect: 'manual',
});
if (!response.ok) {
throw new Error(
`Failed to get config (${response.statusText}) from '${url}'`,
);
}
const { pubKeys } = await response.json();
logger.info('Fetched server public keys:', pubKeys);
return pubKeys;
} catch (e) {
throw new FailedToFetchPublicKeys(
`Failed to fetch public keys from '${url}'`,
{ cause: e },
);
}
}

async importAndVerifyPubKeys(allKeys) {
return new Map(
await Promise.all(
Expand Down

0 comments on commit a319666

Please sign in to comment.