• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3    return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6exports.Root = void 0;
7const util_1 = __importDefault(require("util"));
8const base_1 = require("./base");
9const error_1 = require("./error");
10const key_1 = require("./key");
11const role_1 = require("./role");
12const utils_1 = require("./utils");
13/**
14 * A container for the signed part of root metadata.
15 *
16 * The top-level role and metadata file signed by the root keys.
17 * This role specifies trusted keys for all other top-level roles, which may further delegate trust.
18 */
19class Root extends base_1.Signed {
20    constructor(options) {
21        super(options);
22        this.type = base_1.MetadataKind.Root;
23        this.keys = options.keys || {};
24        this.consistentSnapshot = options.consistentSnapshot ?? true;
25        if (!options.roles) {
26            this.roles = role_1.TOP_LEVEL_ROLE_NAMES.reduce((acc, role) => ({
27                ...acc,
28                [role]: new role_1.Role({ keyIDs: [], threshold: 1 }),
29            }), {});
30        }
31        else {
32            const roleNames = new Set(Object.keys(options.roles));
33            if (!role_1.TOP_LEVEL_ROLE_NAMES.every((role) => roleNames.has(role))) {
34                throw new error_1.ValueError('missing top-level role');
35            }
36            this.roles = options.roles;
37        }
38    }
39    addKey(key, role) {
40        if (!this.roles[role]) {
41            throw new error_1.ValueError(`role ${role} does not exist`);
42        }
43        if (!this.roles[role].keyIDs.includes(key.keyID)) {
44            this.roles[role].keyIDs.push(key.keyID);
45        }
46        this.keys[key.keyID] = key;
47    }
48    equals(other) {
49        if (!(other instanceof Root)) {
50            return false;
51        }
52        return (super.equals(other) &&
53            this.consistentSnapshot === other.consistentSnapshot &&
54            util_1.default.isDeepStrictEqual(this.keys, other.keys) &&
55            util_1.default.isDeepStrictEqual(this.roles, other.roles));
56    }
57    toJSON() {
58        return {
59            _type: this.type,
60            spec_version: this.specVersion,
61            version: this.version,
62            expires: this.expires,
63            keys: keysToJSON(this.keys),
64            roles: rolesToJSON(this.roles),
65            consistent_snapshot: this.consistentSnapshot,
66            ...this.unrecognizedFields,
67        };
68    }
69    static fromJSON(data) {
70        const { unrecognizedFields, ...commonFields } = base_1.Signed.commonFieldsFromJSON(data);
71        const { keys, roles, consistent_snapshot, ...rest } = unrecognizedFields;
72        if (typeof consistent_snapshot !== 'boolean') {
73            throw new TypeError('consistent_snapshot must be a boolean');
74        }
75        return new Root({
76            ...commonFields,
77            keys: keysFromJSON(keys),
78            roles: rolesFromJSON(roles),
79            consistentSnapshot: consistent_snapshot,
80            unrecognizedFields: rest,
81        });
82    }
83}
84exports.Root = Root;
85function keysToJSON(keys) {
86    return Object.entries(keys).reduce((acc, [keyID, key]) => ({ ...acc, [keyID]: key.toJSON() }), {});
87}
88function rolesToJSON(roles) {
89    return Object.entries(roles).reduce((acc, [roleName, role]) => ({ ...acc, [roleName]: role.toJSON() }), {});
90}
91function keysFromJSON(data) {
92    let keys;
93    if (utils_1.guard.isDefined(data)) {
94        if (!utils_1.guard.isObjectRecord(data)) {
95            throw new TypeError('keys must be an object');
96        }
97        keys = Object.entries(data).reduce((acc, [keyID, keyData]) => ({
98            ...acc,
99            [keyID]: key_1.Key.fromJSON(keyID, keyData),
100        }), {});
101    }
102    return keys;
103}
104function rolesFromJSON(data) {
105    let roles;
106    if (utils_1.guard.isDefined(data)) {
107        if (!utils_1.guard.isObjectRecord(data)) {
108            throw new TypeError('roles must be an object');
109        }
110        roles = Object.entries(data).reduce((acc, [roleName, roleData]) => ({
111            ...acc,
112            [roleName]: role_1.Role.fromJSON(roleData),
113        }), {});
114    }
115    return roles;
116}
117