gristlabs_grist-core/app/common/EncActionBundle.ts

74 lines
3.1 KiB
TypeScript
Raw Normal View History

/**
* Types for encrypted ActionBundles that get sent between instances and hub.
*/
import {ActionInfo, Envelope} from 'app/common/ActionBundle';
import {DocAction} from 'app/common/DocActions';
// Type representing a point in time as milliseconds since Epoch.
export type Timestamp = number;
// Type representing binary data encoded as a base64 string.
export type Base64String = string;
// Metadata about a symmetric encryption key.
export interface KeyInfo {
firstActionNum: number; // ActionNum of first action for which this key was used.
firstUsedTime: Timestamp; // Timestamp of first action for which this key was used.
}
// Encrypted symmetric key with metadata, sent from hub to instance with each envelope.
export interface EncKeyInfo extends KeyInfo {
encryptedKey: Base64String; // Symmetric key encrypted with the recipient's public key.
}
// Bundle of encryptions of the symmetric key. Note that the hub will store EncKeyBundles for
// lookup, indexed by the combination {recipients: string[], firstActionNum: number}.
export interface EncKeyBundle extends KeyInfo {
encryptedKeys: {
// Map of instanceId to the symmetric key encrypted with that instance's public key.
// A single symmetric key is used for all, and only present here in encrypted form.
[instanceId: string]: Base64String;
};
}
// This allows reorganizing ActionBundle by envelope while preserving order information for
// actions. E.g. if ActionBundle contains {stored: [(0,A), (1,B), (2,C), (0,D)], then we'll have:
// - in envelopes 0: {stored: [[0, A], [3, D]]}
// - in envelopes 1: {stored: [[1, B]]}
// - in envelopes 2: {stored: [[2, C]]}
// Then recipients of multiple envelopes can sort actions by index to get their correct order.
export interface DecryptedEnvelopeContent {
info?: ActionInfo;
// number is the index into the bundle-wide array of 'stored' or 'calc' DocActions.
stored: Array<[number, DocAction]>;
calc: Array<[number, DocAction]>;
}
export type DecryptedEnvelope = Envelope & DecryptedEnvelopeContent;
// Sent from instance to hub.
export interface EncEnvelopeToHub extends Envelope {
encKeyReused?: number; // If reusing a key, firstActionNum of the key being reused.
encKeyBundle?: EncKeyBundle; // If created a new key, its encryption for all recipients.
content: Base64String; // Marshalled and encrypted DecryptedEnvelopeContent as a base64 string.
}
// Sent from hub to instance.
export interface EncEnvelopeFromHub extends Envelope {
encKeyInfo: EncKeyInfo;
content: Base64String; // Marshalled and encrypted DecryptedEnvelopeContent as a base64 string.
}
// EncActionBundle is an encrypted version of ActionBundle. It comes in two varieties, one for
// sending ActionBundle to the hub, and one for receiving from the hub.
export interface EncActionBundle<EncEnvelope> {
actionNum: number;
actionHash: string|null;
parentActionHash: string|null;
envelopes: EncEnvelope[];
}
export type EncActionBundleToHub = EncActionBundle<EncEnvelopeToHub>;
export type EncActionBundleFromHub = EncActionBundle<EncEnvelopeFromHub>;