dnp-client
Version:
数据基础设施轻量连接器,帮助用户管理身份凭证、区域节点、业务节点,完成身份集成。
228 lines (222 loc) • 9.49 kB
JavaScript
import { v7 as t } from "uuid";
class i {
constructor(t = {}) {
const {options: o = {}, callbacks: s = {}} = t;
this.options = {
pollingTimeout: 6e5,
pollingInterval: 1e3,
dnpServerUrl: "http://localhost:3521",
apiEndpoints: {
getToken: "/get/token",
getCert: "/get/cert",
importCert: "/import/cert"
},
baseUrl: "undefined" != typeof window ? `${window.location.origin}/api/v1` : "",
type: 1,
clientType: i.detectClientType(),
...o
}, this.uuidString = "", this.startTime = 0, this.isPolling = !1, this.pollingTimer = null,
this.callbacks = {
onLoading: t => {},
onSuccess: t => {},
onError: t => {},
onMessage: (t, i = "info") => {},
...s
}, this.login = this.login.bind(this), this.stopPolling = this.stopPolling.bind(this),
this.clickAuthLogin = this.clickAuthLogin.bind(this), this.registerIdentity = this.registerIdentity.bind(this),
this.importCert = this.importCert.bind(this);
}
static detectClientType() {
return "undefined" == typeof window ? "server" : "function" == typeof window.sendToMain ? "electron" : "browser";
}
async login() {
try {
this.stopPolling(), this.callbacks.onLoading(!0), await this.clickAuthLogin();
} catch (t) {
this.callbacks.onError(t), this.callbacks.onLoading(!1);
}
}
async clickAuthLogin() {
this.uuidString = t().slice(0, 32), "electron" !== this.options.clientType ? this.invokeDesktopApp(`dnp://getToken?json=${JSON.stringify({
uuid: this.uuidString,
baseUrl: this.options.baseUrl,
type: this.options.type
})}`, () => this.invokeDesktopAppLogin()) : "function" == typeof window.sendToMain ? (window.sendToMain({
type: "login",
data: {
uuid: this.uuidString
}
}), this.invokeDesktopAppLogin()) : (this.callbacks.onMessage("统一身份登录暂时不可用,请使用其他登录方式", "error"),
this.callbacks.onLoading(!1));
}
invokeDesktopApp(t, i) {
try {
const o = document.createElement("iframe");
o.style.display = "none", o.src = t, document.body.appendChild(o), setTimeout(() => {
document.body.removeChild(o);
}, 1e3), i && "function" == typeof i && i();
} catch (t) {
this.callbacks.onError(t), this.callbacks.onLoading(!1);
}
}
invokeDesktopAppLogin() {
this.stopPolling(), this.startTime = Date.now(), this.isPolling = !0, this.waitForVP();
}
async waitForVP() {
if (this.isPolling) {
if (Date.now() - this.startTime >= this.options.pollingTimeout) return this.stopPolling(),
this.callbacks.onMessage("获取签名失败", "error"), void this.callbacks.onLoading(!1);
try {
const t = await this.apiGetToken(this.uuidString);
if (t) return "refuse" === t ? (this.stopPolling(), this.callbacks.onMessage("客户端正忙,请稍后再试", "error"),
void this.callbacks.onLoading(!1)) : t.data?.tokenValue ? (this.stopPolling(), this.callbacks.onSuccess(t.data.tokenValue),
void this.callbacks.onLoading(!1)) : void (this.pollingTimer = setTimeout(() => {
this.waitForVP();
}, this.options.pollingInterval));
this.pollingTimer = setTimeout(() => {
this.waitForVP();
}, this.options.pollingInterval);
} catch (t) {
this.pollingTimer = setTimeout(() => {
this.waitForVP();
}, this.options.pollingInterval);
}
}
}
stopPolling() {
this.isPolling = !1, this.pollingTimer && (clearTimeout(this.pollingTimer), this.pollingTimer = null);
}
async apiGetToken(t) {
const i = `${this.options.dnpServerUrl}${this.options.apiEndpoints.getToken}?uuid=${t}`, o = await fetch(i, {
method: "GET",
headers: {
"Content-Type": "application/json"
}
});
if (!o.ok) throw new Error(`HTTP error! status: ${o.status}`);
return o.json();
}
async registerIdentity({didMethod: t, subject: i} = {}) {
try {
this.stopPolling(), this.callbacks.onLoading(!0), await this.invokeDesktopAppRegister(t, i);
} catch (t) {
this.callbacks.onError(t), this.callbacks.onLoading(!1);
}
}
async invokeDesktopAppRegister(i, o) {
this.uuidString = t().slice(0, 32);
const s = {
uuid: this.uuidString
};
i && (s.didMethod = i), o && (s.subject = o), "electron" !== this.options.clientType ? this.invokeDesktopApp(`dnp://genKeys?json=${JSON.stringify(s)}`, () => this.invokeDesktopAppRegisterFlow()) : "function" == typeof window.sendToMain ? (window.sendToMain({
type: "register",
data: s
}), this.invokeDesktopAppRegisterFlow()) : (this.callbacks.onMessage("身份注册暂时不可用,请使用其他方式", "error"),
this.callbacks.onLoading(!1));
}
invokeDesktopAppRegisterFlow() {
this.stopPolling(), this.startTime = Date.now(), this.isPolling = !0, this.waitForDid();
}
async waitForDid() {
if (this.isPolling) {
if (Date.now() - this.startTime >= this.options.pollingTimeout) return this.stopPolling(),
this.callbacks.onMessage("身份注册超时", "error"), void this.callbacks.onLoading(!1);
try {
const t = await this.apiGetCert("uuid", this.uuidString);
if (t) {
if ("refuse" === t) return this.stopPolling(), this.callbacks.onMessage("客户端正忙,请稍后再试", "error"),
void this.callbacks.onLoading(!1);
if (t.data) {
this.stopPolling();
const i = t.data;
return this.callbacks.onSuccess(i), void this.callbacks.onLoading(!1);
}
}
Date.now() - this.startTime < this.options.pollingTimeout ? this.pollingTimer = setTimeout(() => {
this.waitForDid();
}, this.options.pollingInterval) : (this.stopPolling(), this.callbacks.onMessage("身份注册超时", "error"),
this.callbacks.onLoading(!1));
} catch (t) {
Date.now() - this.startTime < this.options.pollingTimeout ? this.pollingTimer = setTimeout(() => {
this.waitForDid();
}, this.options.pollingInterval) : (this.stopPolling(), this.callbacks.onMessage("身份注册超时", "error"),
this.callbacks.onLoading(!1));
}
}
}
async apiGetCert(t, i) {
const o = `${this.options.dnpServerUrl}${this.options.apiEndpoints.getCert}?key=${t}&code=${i}`, s = await fetch(o, {
method: "GET",
headers: {
"Content-Type": "application/json"
}
});
if (!s.ok) throw new Error(`HTTP error! status: ${s.status}`);
return s.json();
}
async importCert(t) {
try {
this.stopPolling(), this.callbacks.onLoading(!0), await this.invokeDesktopAppImportVc(t);
} catch (t) {
this.callbacks.onError(t), this.callbacks.onLoading(!1);
}
}
async invokeDesktopAppImportVc(t) {
"electron" !== this.options.clientType ? this.invokeDesktopApp("dnp://import-vc", () => this.invokeDesktopAppImportVcFlow(t)) : "function" == typeof window.sendToMain ? (window.sendToMain({
type: "importCert",
data: t
}), this.invokeDesktopAppImportVcFlow(t)) : (this.callbacks.onMessage("身份凭证导入暂时不可用,请使用其他方式", "error"),
this.callbacks.onLoading(!1));
}
invokeDesktopAppImportVcFlow(t) {
this.stopPolling(), this.startTime = Date.now(), this.isPolling = !0, this.pushVCToClient(t);
}
async pushVCToClient(t) {
if (this.isPolling) {
if (Date.now() - this.startTime >= this.options.pollingTimeout) return this.stopPolling(),
this.callbacks.onMessage("VC导入超时", "error"), void this.callbacks.onLoading(!1);
try {
const i = await this.apiPushCert(t);
if (i) {
if ("refuse" === i) return this.stopPolling(), this.callbacks.onMessage("客户端正忙,请稍后再试", "error"),
void this.callbacks.onLoading(!1);
if (i.data) return this.stopPolling(), this.callbacks.onMessage("VC导入成功", "success"),
this.callbacks.onSuccess(i), void this.callbacks.onLoading(!1);
}
Date.now() - this.startTime < this.options.pollingTimeout ? this.pollingTimer = setTimeout(() => {
this.isPolling && this.pushVCToClient(t);
}, this.options.pollingInterval) : (this.stopPolling(), this.callbacks.onMessage("VC导入超时", "error"),
this.callbacks.onLoading(!1));
} catch (i) {
Date.now() - this.startTime < this.options.pollingTimeout ? this.pollingTimer = setTimeout(() => {
this.isPolling && this.pushVCToClient(t);
}, this.options.pollingInterval) : (this.stopPolling(), this.callbacks.onMessage("VC导入失败", "error"),
this.callbacks.onLoading(!1));
}
}
}
async apiPushCert(t) {
const i = `${this.options.dnpServerUrl}${this.options.apiEndpoints.importCert}`, o = await fetch(i, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(t)
});
if (!o.ok) throw new Error(`HTTP error! status: ${o.status}`);
return o.json();
}
destroy() {
this.stopPolling(), this.callbacks = {};
}
}
function createDnpLogin(t = {}) {
return new i(t);
}
function createDnpRegister(t = {}) {
return new i(t);
}
function createDnpImportVc(t = {}) {
return new i(t);
}
export { createDnpImportVc, createDnpLogin, createDnpRegister, i as default };