UNPKG

@nopwdio/sdk-js

Version:
178 lines 7.61 kB
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 @click=${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