@nopwdio/sdk-js
Version:
Nopwd JS SDK
178 lines • 7.61 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
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());
});
};
// Import necessary modules and components from lit and internal styles
import { LitElement, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { core } from "../internal/styles/core.styles.js";
import { component } from "../internal/styles/semantic.styles.js";
import styles from "./np-passkey-register.styles.js";
import { checkSolid, fingerprint, busy, exclamationCircle, } from "../internal/styles/icons.styles.js";
import { AbortError } from "../internal/api/errors.js";
import { register } from "../core/webauthn.js";
import { get } from "../core/session.js";
// Define the possible states for the component
export var State;
(function (State) {
State["REGISTERING"] = "registering";
State["REGISTERED"] = "registered";
State["ERROR"] = "error";
})(State || (State = {}));
/**
* @summary `np-passkey-register` is a custom element that facilitates the creation of a passkey for this website.
*
* @description
* This component manages the registration process of a passkey, providing visual feedback during the process.
* It handles user interactions, communicates with the WebAuthn API, and manages the component's state.
* The component emits events to notify the parent application when the registration is successful or if an error occurs.
*
* @slot - The default slot for the button label.
* @slot registering - Content displayed while the registration is in progress.
* @slot registered - Content displayed when the passkey has been successfully created.
* @slot error - Content displayed when an error occurs during registration.
*
* @event np:register - Emitted when the registration process completes successfully.
* @event np:error - Emitted when an error occurs during the registration process.
*
* @csspart button - The component's button element.
*/
let NpPasskeyRegister = class NpPasskeyRegister extends LitElement {
constructor() {
super(...arguments);
/** The component's state. */
this.state = undefined;
this.resetDuration = 2000;
this.stateTimeoutId = null;
this.abort = null;
}
// Lifecycle method called when the component is added to the DOM
connectedCallback() {
const _super = Object.create(null, {
connectedCallback: { get: () => super.connectedCallback }
});
return __awaiter(this, void 0, void 0, function* () {
_super.connectedCallback.call(this);
});
}
// Lifecycle method called when the component is removed from the DOM
disconnectedCallback() {
const _super = Object.create(null, {
disconnectedCallback: { get: () => super.disconnectedCallback }
});
return __awaiter(this, void 0, void 0, function* () {
_super.disconnectedCallback.call(this);
this.cancel();
});
}
// Handle button click event to start the registration process
onClick() {
return __awaiter(this, void 0, void 0, function* () {
return yield this.register();
});
}
// Register a new passkey
register() {
return __awaiter(this, void 0, void 0, function* () {
if (this.state) {
return;
}
try {
const session = yield get();
if (!session) {
throw new Error("You must be authenticated to create a passkey");
}
this.abort = new AbortController();
this.state = State.REGISTERING;
const { id } = yield register(session.token, this.abort.signal);
this.state = State.REGISTERED;
this.dispatchRegisterEvent(id);
this.resetState(this.resetDuration);
}
catch (e) {
if (e instanceof AbortError) {
return this.resetState();
}
this.state = State.ERROR;
this.dispatchErrorEvent(e);
this.resetState(this.resetDuration);
}
finally {
this.abort = null;
}
});
}
// Cancel the registration process
cancel() {
if (this.abort) {
this.abort.abort();
this.abort = null;
}
this.resetState();
}
// Reset the component state after a specified duration
resetState(ms = 0) {
return new Promise((resolve) => {
if (this.stateTimeoutId) {
window.clearTimeout(this.stateTimeoutId);
this.stateTimeoutId = null;
}
this.stateTimeoutId = window.setTimeout(() => {
this.state = undefined;
}, ms);
});
}
// Dispatch a custom event when registration is successful
dispatchRegisterEvent(kid) {
this.dispatchEvent(new CustomEvent("np:register", {
composed: true,
cancelable: true,
bubbles: true,
detail: { kid },
}));
}
// Dispatch a custom event when an error occurs
dispatchErrorEvent(e) {
this.dispatchEvent(new CustomEvent("np:error", {
composed: true,
cancelable: true,
bubbles: true,
detail: e,
}));
}
// Render the UI as a function of component state
render() {
return html `<button =${this.onClick} part="button">
${!this.state
? html `${fingerprint}<slot>Create a passkey</slot>`
: this.state === State.REGISTERING
? html `${busy}<slot name="registering">Creating...</slot>`
: this.state === State.REGISTERED
? html `${checkSolid}<slot name="registered">Passkey created!</slot>`
: html `${exclamationCircle}<slot name="error">Create a passkey</slot>`}
</button>`;
}
};
NpPasskeyRegister.styles = [core, component, styles];
__decorate([
property({ reflect: true })
], NpPasskeyRegister.prototype, "state", void 0);
__decorate([
property({ type: Number })
], NpPasskeyRegister.prototype, "resetDuration", void 0);
NpPasskeyRegister = __decorate([
customElement("np-passkey-register")
], NpPasskeyRegister);
export { NpPasskeyRegister };
//# sourceMappingURL=np-passkey-register.js.map