UNPKG

moeralib

Version:

Library to interact with Moera decentralized social network

125 lines (124 loc) 5.52 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.generateCarte = exports.MoeraCarteSource = exports.MoeraCartesError = void 0; const crypto_1 = __importDefault(require("crypto")); const util_1 = require("util"); const types_1 = require("./types"); const fingerprints_1 = require("./fingerprints"); const crypto_2 = require("../crypto"); /** * Error obtaining valid cartes. */ class MoeraCartesError extends Error { /** * @param {string} message - error message */ constructor(message) { super(message); } } exports.MoeraCartesError = MoeraCartesError; /** * Class that gets cartes from the given node, caches them and supplies them for authentication. */ class MoeraCarteSource { /** * @param {MoeraNode} node node to get cartes from * @param {Scope[] | null} clientScope permissions to be granted to the cartes; if not set, all permissions of * the cartes' owner are granted * @param {Scope[] | null} adminScope additional administrative permissions (of those granted to the cartes' owner * by the target node) to be granted to the cartes * @param {string | null} targetNodeName if set, the cartes are valid for authentication on the specified node only */ constructor(node, clientScope = null, adminScope = null, targetNodeName = null) { this.cartes = []; this.node = node; this.clientScope = clientScope !== null && clientScope !== void 0 ? clientScope : ["all"]; this.adminScope = adminScope !== null && adminScope !== void 0 ? adminScope : []; this.targetNodeName = targetNodeName; } /** * Force renewing the cached list of cartes. */ renew() { return __awaiter(this, void 0, void 0, function* () { const attributes = { clientScope: this.clientScope, adminScope: this.adminScope, nodeName: this.targetNodeName }; this.cartes = (yield this.node.createCartes(attributes)).cartes; }); } /** * Get a valid carte. Use one of the cached ones, if possible. * * @return {Promise<string>} the carte */ getCarte() { return __awaiter(this, void 0, void 0, function* () { for (const renewed of [false, true]) { const now = Math.floor(Date.now() / 1000); this.cartes = this.cartes.filter(c => c.deadline > now); if (this.cartes.length === 0) { if (renewed) { throw new MoeraCartesError("Could not obtain a valid carte from the node"); } yield this.renew(); continue; } for (const c of this.cartes) { if (c.beginning <= now) { return c.carte; } } throw new MoeraCartesError("Could not obtain a carte valid for now"); } throw new MoeraCartesError("Could not obtain a carte valid for now"); }); } } exports.MoeraCarteSource = MoeraCarteSource; function toScopeMask(scope) { let mask = 0; for (const sc of scope) { mask |= types_1.SCOPE_VALUES[sc]; } return mask; } /** * Generate a carte with the given parameters and sign it with the provided private signing key. * * @param {string | null} ownerName - name of the node authenticating with the carte * @param {crypto.KeyObject} signingKey - the private signing key to sign the carte * @param {number} beginning - timestamp of the beginning of the carte's life * @param {GenerateCarteOptions} options - carte options * @return {Promise<string>} the carte */ function generateCarte(ownerName_1, signingKey_1, beginning_1) { return __awaiter(this, arguments, void 0, function* (ownerName, signingKey, beginning, { ttl = 600, address = null, nodeName = null, clientScope = types_1.SCOPE_VALUES["all"], adminScope = 0 } = {}) { if (Array.isArray(clientScope)) { clientScope = toScopeMask(clientScope); } if (Array.isArray(adminScope)) { adminScope = toScopeMask(adminScope); } const salt = yield (0, util_1.promisify)(crypto_1.default.randomBytes)(8); const fingerprint = (0, fingerprints_1.createCarteFingerprint2)(ownerName, address, beginning, beginning + ttl, nodeName, clientScope, adminScope, salt); const signature = (0, crypto_2.signFingerprint)(fingerprint, signingKey); return Buffer.concat([fingerprint, signature]).toString("base64url"); }); } exports.generateCarte = generateCarte;