@tidecloak/js
Version:
TideCloak client side JS SDK
491 lines • 20.8 kB
JavaScript
"use strict";
//
// Tide Protocol - Infrastructure for a TRUE Zero-Trust paradigm
// Copyright (C) 2022 Tide Foundation Ltd
//
// This program is free software and is subject to the terms of
// the Tide Community Open Code License as published by the
// Tide Foundation Limited. You may modify it and redistribute
// it in accordance with and subject to the terms of that License.
// This program is distributed WITHOUT WARRANTY of any kind,
// including without any implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
// See the Tide Community Open Code License for more details.
// You should have received a copy of the Tide Community Open
// Code License along with this program.
// If not, see https://tide.org/licenses_tcoc2-0-0-en
//
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const index_js_1 = require("../Cryptide/index.js");
const GenShardResponse_js_1 = __importDefault(require("../Models/Responses/KeyGen/GenShard/GenShardResponse.js"));
const ClientBase_js_1 = __importDefault(require("./ClientBase.js"));
const SetShardResponse_js_1 = __importDefault(require("../Models/Responses/KeyGen/SetShard/SetShardResponse.js"));
const PrismConvertResponse_js_1 = __importDefault(require("../Models/Responses/KeyAuth/Convert/PrismConvertResponse.js"));
const CMKConvertResponse_js_1 = __importDefault(require("../Models/Responses/KeyAuth/Convert/CMKConvertResponse.js"));
const Serialization_js_1 = require("../Cryptide/Serialization.js");
const ConvertRememberedResponse_js_1 = __importDefault(require("../Models/Responses/KeyAuth/Convert/ConvertRememberedResponse.js"));
const BaseTideRequest_js_1 = __importDefault(require("../Models/BaseTideRequest.js"));
const ReservationConfirmation_js_1 = __importDefault(require("../Models/Responses/Reservation/ReservationConfirmation.js"));
const Ed25519Components_js_1 = require("../Cryptide/Components/Schemes/Ed25519/Ed25519Components.js");
const Ed25519_js_1 = require("../Cryptide/Ed25519.js");
const TideKey_js_1 = __importDefault(require("../Cryptide/TideKey.js"));
const Doken_js_1 = require("../Models/Doken.js");
class NodeClient extends ClientBase_js_1.default {
/**
* @param {string} url
*/
constructor(url) {
super(url);
this.enabledTideDH = false;
}
async isActive() {
const response = await this._get("/active", 3000);
const responseData = await this._handleError(response, "Is Active");
return responseData;
}
/**
* @param {number} index
* @param {string} uid
* @param {string} sessId
* @param {string} voucher
* @param {Point} gSessKeyPub
* @returns
*/
async ReserveUID(index, uid, sessId, voucher, gSessKeyPub) {
const data = this._createFormData({
"sessId": sessId,
"voucher": voucher,
"gSessKeyPub": gSessKeyPub.toBase64()
});
const response = await this._post(`/Authentication/Create/ReserveUserId?uid=${uid}`, data);
const responseData = await this._handleError(response, "Reserve UID");
return {
"index": index,
resConf: ReservationConfirmation_js_1.default.from(responseData)
};
}
/**
* @param {number} index
* @param {string} uid
* @param {Point} gBlurPass
* @param {Ed25519PublicComponent} gSessKeyPub
* @param {boolean} rememberMe
* @param {boolean} cmkCommitted
* @param {boolean} prismCommitted
* @param {string} voucher
* @param {string} m
* @returns
*/
async Convert(index, uid, gBlurPass, gSessKeyPub, rememberMe, voucher, m, cmkCommitted = true, prismCommitted = true) {
const data = this._createFormData({
'gBlurPass': gBlurPass.toBase64(),
'gSessKeyPub': gSessKeyPub.Serialize().ToString(),
'rememberMe': rememberMe,
'cmkCommitted': cmkCommitted,
'prismCommitted': prismCommitted,
'voucher': voucher,
'M': m
});
const response = await this._post(`/Authentication/Auth/Convert?uid=${uid}`, data);
const responseData = await this._handleError(response, "Convert CMK/Prism");
const returnObj = {
"CMKConvertResponse": CMKConvertResponse_js_1.default.from(responseData.split("|")[0]),
"PrismConvertResponse": PrismConvertResponse_js_1.default.from(responseData.split("|")[1])
};
return {
"index": index,
returnObj // only one value is allowed in indexed requests, apart from the index
};
}
/**
* @param {number} index
* @param {string} uid
* @param {Point} gBlurPass
* @param {Ed25519PublicComponent} gSessKeyPub
* @param {string} voucher
* @param {string} m
*/
async ConvertPass(index, uid, gBlurPass, gSessKeyPub, voucher, m) {
const data = this._createFormData({
'gBlurPass': gBlurPass.toBase64(),
'gSessKeyPub': gSessKeyPub.Serialize().ToString(),
'voucher': voucher,
'M': m
});
const response = await this._post(`/Authentication/Auth/ConvertPass?uid=${uid}`, data);
const responseData = await this._handleError(response, "ConvertPass CMK/Prism");
return {
"index": index,
"ConvertPassResponse": PrismConvertResponse_js_1.default.from(responseData)
};
}
/**
* @param {number} index
* @param {string} uid
* @param {string} selfRequesti
* @param {string} voucher
* @returns
*/
async ConvertRemembered(index, uid, selfRequesti, voucher) {
const data = this._createFormData({
'selfRequesti': selfRequesti,
'voucher': voucher
});
const response = await this._post(`/Authentication/Auth/ConvertRemembered?uid=${uid}`, data);
const responseData = await this._handleError(response, "Convert Passwordless");
return {
"index": index,
data: ConvertRememberedResponse_js_1.default.from(responseData)
};
}
/**
* @param {string} uid
* @param {string} selfRequesti
* @param {bigint} blurHCMKMul
* @param {Uint8Array} bitwise
* @param {boolean} cmkCommitted
* @param {boolean} prismCommitted
* @returns {Promise<string>}
*/
async Authenticate(uid, selfRequesti, blurHCMKMul, bitwise, cmkCommitted = true, prismCommitted = true) {
const data = this._createFormData({
'selfRequesti': selfRequesti,
'blurHCMKMul': blurHCMKMul.toString(),
'bitwise': (0, Serialization_js_1.bytesToBase64)(bitwise),
'cmkCommitted': cmkCommitted,
'prismCommitted': prismCommitted
});
const response = await this._post(`/Authentication/Auth/Authenticate?uid=${uid}`, data);
const encSig = await this._handleError(response, "Authenticate");
return encSig;
}
/**
*
* @param {string} uid
* @param {bigint} blurHCMKMul
* @param {Uint8Array} ORKsBitwise
*/
async AuthenticateRemembered(uid, blurHCMKMul, ORKsBitwise) {
const data = this._createFormData({
'blurHCMKMul': blurHCMKMul.toString(),
'bitwise': (0, Serialization_js_1.bytesToBase64)(ORKsBitwise),
});
const response = await this._post(`/Authentication/Auth/AuthenticateRemembered?uid=${uid}`, data);
const encSig = await this._handleError(response, "Authenticate");
return encSig;
}
/**
* @param {number} index
* @param {string} uid
* @param {string} voucher
* @param {string} reservationAuth
* @param {string} purpose
* @param {string[]} mIdORKij
* @param {number} numKeys
* @param {Point[]} gMultipliers
* @param {Point} gSessKeyPub
* @returns {Promise<GenShardResponse>}
*/
async GenShard(index, uid, voucher, reservationAuth, purpose, mIdORKij, numKeys, gMultipliers, gSessKeyPub) {
const data = this._createFormData({
'voucher': voucher,
'reservationAuth': reservationAuth,
'purpose': purpose,
'mIdORKij': mIdORKij,
'numKeys': numKeys,
'gMultipliers': gMultipliers.map(p => p == null ? "" : new Ed25519Components_js_1.Ed25519PublicComponent(p).Serialize().ToString()),
'gSessKeyPub': gSessKeyPub.toBase64()
});
const response = await this._post(`/Authentication/Create/GenShard?uid=${uid}`, data);
const responseData = await this._handleError(response, "GenShard");
const responseModel = GenShardResponse_js_1.default.from(responseData);
return {
index,
responseModel
};
}
/**
* @param {string} uid
* @param {Point} gVRK
* @param {string} auth
* @param {string} authSig
* @param {string[]} mIdORKij
* @param {string} voucher
* @returns {Promise<GenShardResponse>}
*/
async GenVVKShard(uid, gVRK, auth, authSig, mIdORKij, voucher) {
const data = this._createFormData({
'gVRK': gVRK.toBase64(),
'auth': auth,
'authSig': authSig,
'mIdORKij': mIdORKij,
'voucher': voucher
});
const response = await this._post(`/Authentication/Create/GenVVKShard?uid=${uid}`, data);
const responseData = await this._handleError(response, "GenShard");
const responseModel = GenShardResponse_js_1.default.from(responseData);
return responseModel;
}
/**
* @param {number} index
* @param {string} uid
* @param {string} purpose
* @param {Point[]} gMultipliers
* @param {string} auth
* @param {Point} gSessKeyPub
* @returns {Promise<GenShardResponse>}
*/
async UpdateShard(index, uid, purpose, gMultipliers, auth, gSessKeyPub, tag) {
const data = this._createFormData({
'purpose': purpose,
'gMultipliers': gMultipliers.map(p => p == null ? "" : new Ed25519Components_js_1.Ed25519PublicComponent(p).Serialize().ToString()),
'auth': auth,
'gSessKeyPub': gSessKeyPub.toBase64()
});
const response = await this._post(`/Authentication/Create/UpdateShard?uid=${uid}`, data);
const responseData = await this._handleError(response, "UpdateShard");
const responseModel = GenShardResponse_js_1.default.from(responseData);
return {
index,
tag,
responseModel
};
}
/**
* @param {string} uid
* @param {string[]} shares
* @param {string} encAuthi
* @param {Point} gSessKeyPub
* @param {string} keyType
*/
async SetShard(uid, shares, encAuthi, gSessKeyPub, keyType) {
const data = this._createFormData({
'yijCipher': shares,
'encAuthi': encAuthi,
'gSessKeyPub': gSessKeyPub.toBase64()
});
const response = await this._post(`/Authentication/Create/Set${keyType}?uid=${uid}`, data);
const responseData = await this._handleError(response, "SendShard");
return SetShardResponse_js_1.default.from(responseData);
}
/**
* @param {string} uid
* @param {bigint} S
* @param {Point} gSessKeyPub
*/
async Commit(uid, S, gSessKeyPub) {
const data = this._createFormData({
'S': S.toString(),
'gSessKeyPub': gSessKeyPub.toBase64()
});
const response = await this._post(`/Authentication/Create/Commit?uid=${uid}`, data);
const responseData = await this._handleError(response, "Commit");
if (responseData !== "Key Created")
Promise.reject("Commit: Account creation failed");
}
/**
* @param {Point} orkPublic
*/
async EnableTideDH(orkPublic) {
if (!this.sessionKeyPrivateRaw)
throw Error("Add a session key to the client first");
this.enabledTideDH = true;
this.DHKey = await index_js_1.DH.computeSharedKey(orkPublic, this.sessionKeyPrivateRaw);
return this;
}
/**
* @param {number} index
* @param {string} vuid
* @param {BaseTideRequest} request
* @param {string} voucher
*/
async PreSign(index, vuid, request, voucher) {
if (!this.enabledTideDH)
throw Error("TideDH must be enabled");
const encrypted = await index_js_1.AES.encryptData((0, Serialization_js_1.CreateTideMemoryFromArray)([request.encode()]), this.DHKey);
const data = this._createFormData({
'encrypted': encrypted,
'voucher': voucher
});
if (!this.token)
data.append("gSessKey", this.sessionKeyPublicEncoded);
const response = await this._post(`/Authentication/Key/v1/PreSign?vuid=${vuid}`, data);
const responseData = await this._handleError(response, 'PreSign');
const decrypted = await index_js_1.AES.decryptDataRawOutput((0, Serialization_js_1.base64ToBytes)(responseData), this.DHKey);
if (decrypted.length % 32 != 0)
throw new Error("Unexpected response legnth. Must be divisible by 32");
let GRis = [];
for (let i = 0; i < decrypted.length; i += 32) {
GRis.push(Ed25519_js_1.Point.fromBytes(decrypted.slice(i, i + 32)));
}
return {
index,
GRis
};
}
/**
*
* @param {string} vuid
* @param {BaseTideRequest} request
* @param {Point[]} GRs
* @param {Uint8Array} bitwise
*/
async Sign(vuid, request, GRs, bitwise) {
if (!this.enabledTideDH)
throw Error("TideDH must be enabled");
const payload = (0, Serialization_js_1.CreateTideMemoryFromArray)([
request.encode(),
(0, Serialization_js_1.ConcatUint8Arrays)([new Uint8Array([GRs.length]), ...GRs.map(r => r.toRawBytes())])
]);
const encrypted = await index_js_1.AES.encryptData(payload, this.DHKey);
const data = this._createFormData({
'encrypted': encrypted,
'bitwise': (0, Serialization_js_1.bytesToBase64)(bitwise)
});
if (!this.token)
data.append("gSessKey", this.sessionKeyPublicEncoded);
const response = await this._post(`/Authentication/Key/v1/Sign?vuid=${vuid}`, data);
const responseData = await this._handleError(response, 'Sign');
const decrypted = await index_js_1.AES.decryptDataRawOutput((0, Serialization_js_1.base64ToBytes)(responseData), this.DHKey);
let Sij = [];
for (let i = 0; i < decrypted.length; i += 32) {
Sij.push((0, Serialization_js_1.BigIntFromByteArray)(decrypted.slice(i, i + 32)));
}
return Sij;
}
/**
* @param {number} index
* @param {string} vuid
* @param {BaseTideRequest} request
* @param {string} voucher
*/
async Decrypt(index, vuid, request, voucher) {
if (!this.enabledTideDH)
throw Error("TideDH must be enabled");
const encrypted = await index_js_1.AES.encryptData((0, Serialization_js_1.CreateTideMemoryFromArray)([request.encode()]), this.DHKey);
const data = this._createFormData({
'encrypted': encrypted,
'voucher': voucher
});
if (!this.token)
data.append("gSessKey", this.sessionKeyPublicEncoded);
const response = await this._post(`/Authentication/Key/v1/Decrypt?vuid=${vuid}`, data);
const responseData = await this._handleError(response, 'Decrypt');
const decrypted = await index_js_1.AES.decryptDataRawOutput((0, Serialization_js_1.base64ToBytes)(responseData), this.DHKey);
if (decrypted.length % 32 != 0)
throw new Error("Unexpected response legnth. Must be divisible by 32");
let appliedC1s = [];
for (let i = 0; i < decrypted.length; i += 32) {
appliedC1s.push(Ed25519_js_1.Point.fromBytes(decrypted.slice(i, i + 32)));
}
return {
index,
appliedC1s
};
}
/**
* @param {number} i
* @param {string} uid
* @param {Point} gSessKeyPub
* @param {bigint} channelId
* @param {string} homeOrkUrl
* @param {string} voucher
*/
async RecoverAccount(i, uid, gSessKeyPub, channelId, homeOrkUrl, voucher) {
const data = this._createFormData({
'gSessKeyPub': gSessKeyPub.toBase64(),
'homeOrkUrl': homeOrkUrl,
'channelId': channelId.toString(),
'voucher': voucher
});
const response = await this._post(`/Authentication/AccountRecovery/StartRecovery?aruid=${uid}`, data);
const responseData = await this._handleError(response, "StartRecovery");
if (responseData !== "Email sent successfully")
throw Error("orks.failedToSendEmail");
return {
index: i,
responseData
};
}
async FinalizeAccountRecovery(uid, channelId) {
const response = await this._post(`/Authentication/AccountRecovery/CleanUpSession?uid=${uid}&channelId=${channelId}`, {});
const responseData = await this._handleError(response, "CleanUpRecovery");
if (responseData !== "Session has been cleaned up")
throw Error("orks.errorFinalizingAccountRecovery");
return { responseData };
}
async CreateCheckoutSession(vendorData, redirectUrl, licensingTier) {
const licenseRequest = {
VendorData: vendorData,
RedirectUri: redirectUrl,
LicensingTier: licensingTier
};
return await this._postJSON(`/Payer/License/CreateCheckoutSession`, licenseRequest);
}
async IsLicenseActive(vendorId) {
const response = await this._getSilent(`/Payer/License/IsLicenseActive?obfGVVK=${vendorId}`);
const text = await response.text();
const isActive = text.trim().toLowerCase() === 'true';
return isActive;
}
async GetLicenseDetails(vendorId, timestamp, timestampSig) {
const data = this._createFormData({
"timestamp": timestamp,
"timestampSig": timestampSig
});
const response = await this._postSilent(`/Payer/License/getLicenseDetails?obfGVVK=${vendorId}`, data);
const responseData = await response.text();
if (responseData.startsWith("--FAILED--")) {
console.log("Error getting license details: " + responseData);
return;
}
return responseData;
}
async GetSubscriptionStatus(vendorId, initialSessionId, timestamp, timestampSig) {
const data = this._createFormData({
"initialSessionId": initialSessionId,
"timestamp": timestamp,
"timestampSig": timestampSig
});
const response = await this._postSilent(`/Payer/License/GetSubscriptionStatus?obfGVVK=${vendorId}`, data);
const responseData = await response.text();
if (responseData.startsWith("--FAILED--")) {
console.log("Error getting license details: " + responseData);
return;
}
const status = responseData.toLowerCase() === "active" ? "upcoming renewal" : responseData.toLowerCase();
return status;
}
async CreateCustomerPortalSession(vendorId, redirectUrl, timestamp, timestampSig) {
const data = this._createFormData({
"vendorId": vendorId,
"timestamp": timestamp,
"timestampSig": timestampSig,
"redirectUrl": redirectUrl
});
return await this._postSilent(`/Payer/License/CreateCustomerPortalSession?obfGVVK=${vendorId}`, data);
}
async UpdateSubscription(updateRequest, licenseId, timestamp, timestampSig) {
const data = this._createFormData({
"updateRequest": JSON.stringify(updateRequest),
"licenseId": licenseId,
"timestamp": timestamp,
"timestampSig": timestampSig
});
return await this._postSilent(`/Payer/License/updateSubscription`, data);
}
async CancelSubscription(licenseId, initialSessionId, timestamp, timestampSig) {
const data = this._createFormData({
"licenseId": licenseId,
"initialSessionId": initialSessionId,
"timestamp": timestamp,
"timestampSig": timestampSig
});
return await this._postSilent(`/Payer/License/CancelSubscription`, data);
}
}
exports.default = NodeClient;
//# sourceMappingURL=NodeClient.js.map