@syndew/oluso-sdk 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,210 @@
1
+ "use strict";var OlusoAuth=(()=>{var Z=Object.defineProperty;var Ee=Object.getOwnPropertyDescriptor;var Te=Object.getOwnPropertyNames;var Ae=Object.prototype.hasOwnProperty;var Re=(i,e)=>{for(var n in e)Z(i,n,{get:e[n],enumerable:!0})},Ue=(i,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Te(e))!Ae.call(i,s)&&s!==n&&Z(i,s,{get:()=>e[s],enumerable:!(o=Ee(e,s))||o.enumerable});return i};var Oe=i=>Ue(Z({},"__esModule",{value:!0}),i);var tt={};Re(tt,{close:()=>q,getUser:()=>Xe,hasPermission:()=>Ze,hasRole:()=>Qe,init:()=>Ve,logout:()=>et,onAuth:()=>Ge,open:()=>Ye,signInWithFedCM:()=>ke,signInWithPasskey:()=>ve});var z=class{constructor(e){this.listeners=new Map;if(!e.serverUrl)throw new Error("serverUrl is required");this.config={...e,serverUrl:e.serverUrl.replace(/\/$/,"")},this.fetchFn=e.fetch||globalThis.fetch.bind(globalThis)}async getJourney(e){return await this.request(`/api/public/journeys/${encodeURIComponent(e)}`)}async submit(e,n,o){try{let s=await this.request(`/api/public/journeys/${encodeURIComponent(e)}/submit`,{method:"POST",body:{data:n,metadata:{...o?.metadata,referrer:typeof document<"u"?document.referrer:void 0,userAgent:typeof navigator<"u"?navigator.userAgent:void 0},honeypot:o?.honeypot}});return this.emit({type:"submission:success",slug:e,data:s}),s}catch(s){throw this.emit({type:"submission:error",slug:e,error:s instanceof Error?s:new Error(String(s))}),s}}async startJourney(e,n){let o=await this.request(`/api/public/journeys/${encodeURIComponent(e)}/start`,{method:"POST",body:{data:n}});return this.emit({type:"journey:started",slug:o.slug,sessionId:o.sessionId,data:o}),o}async startAuthJourney(e,n,o){let s=await this.request(`/api/public/journeys/${encodeURIComponent(e)}/start`,{method:"POST",body:{data:o,clientId:n.clientId,codeChallenge:n.codeChallenge,codeChallengeMethod:"S256",scope:n.scope}});return this.emit({type:"journey:started",slug:s.slug,sessionId:s.sessionId,data:s}),s}async submitStep(e,n,o){let s=await this.request(`/api/public/journeys/sessions/${encodeURIComponent(e)}/step`,{method:"POST",body:{data:n,action:o}});return this.emit({type:s.completed?"journey:completed":s.success?"journey:step":"journey:error",slug:s.slug,sessionId:e,data:s}),s}async submitStepForm(e,n,o){o&&n.set("__journey_action",o);let s=await this.request(`/api/public/journeys/sessions/${encodeURIComponent(e)}/step`,{method:"POST",body:n});return this.emit({type:s.completed?"journey:completed":s.success?"journey:step":"journey:error",slug:s.slug,sessionId:e,data:s}),s}get serverUrl(){return this.config.serverUrl}async getSession(e){return this.request(`/api/public/journeys/sessions/${encodeURIComponent(e)}`)}getJourneyUrl(e,n){let o=new URLSearchParams;return this.config.tenant&&o.set("tenant",this.config.tenant),n?.redirectUri&&o.set("redirect_uri",n.redirectUri),n?.state&&o.set("state",n.state),`${this.config.serverUrl}/journey/start/${encodeURIComponent(e)}?${o}`}getEmbedUrl(e,n){let o=new URLSearchParams({embed:"true"});return this.config.tenant&&o.set("tenant",this.config.tenant),n?.theme&&o.set("theme",n.theme),n?.hideHeader&&o.set("hideHeader","true"),`${this.config.serverUrl}/journey/start/${encodeURIComponent(e)}?${o}`}on(e,n){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(n),()=>{this.listeners.get(e)?.delete(n)}}off(e,n){this.listeners.get(e)?.delete(n)}emit(e){this.listeners.get(e.type)?.forEach(n=>n(e)),this.listeners.get("*")?.forEach(n=>n(e))}async request(e,n){let o=`${this.config.serverUrl}${e}`,s=n?.method||"GET",a=typeof FormData<"u"&&n?.body instanceof FormData,g={};this.config.tenant&&(g["X-Tenant-ID"]=this.config.tenant),a||(g["Content-Type"]="application/json"),this.config.apiKey&&(g["X-API-Key"]=this.config.apiKey),this.config.headers&&Object.assign(g,await this.config.headers({method:s,url:o}));let m=await this.fetchFn(o,{method:s,headers:g,body:n?.body===void 0?void 0:a?n.body:JSON.stringify(n.body),credentials:"include"});if(!m.ok){let f=await m.json().catch(()=>({message:m.statusText}));throw new ee(f.message||`Request failed: ${m.status}`,m.status,f.code,f.errors)}return m.json()}},ee=class extends Error{constructor(n,o,s,a){super(n);this.status=o;this.code=s;this.fieldErrors=a;this.name="OlusoError"}};var Pe={eq:"eq",equals:"eq","==":"eq","=":"eq",ne:"ne",neq:"ne",notequals:"ne","!=":"ne",gt:"gt",">":"gt",greaterthan:"gt",gte:"gte",">=":"gte",greaterthanorequals:"gte",lt:"lt","<":"lt",lessthan:"lt",lte:"lte","<=":"lte",lessthanorequals:"lte",contains:"contains",notcontains:"not_contains","!contains":"not_contains",startswith:"starts_with",endswith:"ends_with",exists:"exists",notnull:"exists",isset:"exists",notexists:"not_exists",null:"not_exists",isnotset:"not_exists",empty:"empty",notempty:"not_empty",in:"in",notin:"not_in","!in":"not_in",regex:"regex",matches:"regex",true:"true",false:"false"};function Le(i){if(i)return Pe[i.trim().toLowerCase().replace(/_/g,"")]}var B=(i,e)=>i.localeCompare(e,void 0,{sensitivity:"accent"})===0;function K(i,e){if(e===void 0)return;let n=Number(i),o=Number(e);if(i.trim()!==""&&e.trim()!==""&&!Number.isNaN(n)&&!Number.isNaN(o))return n===o?0:n<o?-1:1;let s=Date.parse(i),a=Date.parse(e);return!Number.isNaN(s)&&!Number.isNaN(a)?s===a?0:s<a?-1:1:i.localeCompare(e,void 0,{sensitivity:"accent"})}function te(i,e,n){let o=i.toLowerCase(),s=(n??"").toLowerCase();switch(e){case"eq":return B(i,n??"");case"ne":return!B(i,n??"");case"gt":{let a=K(i,n);return a!==void 0&&a>0}case"gte":{let a=K(i,n);return a!==void 0&&a>=0}case"lt":{let a=K(i,n);return a!==void 0&&a<0}case"lte":{let a=K(i,n);return a!==void 0&&a<=0}case"contains":return o.includes(s);case"not_contains":return!o.includes(s);case"starts_with":return o.startsWith(s);case"ends_with":return o.endsWith(s);case"regex":if(!n)return!1;try{return new RegExp(n,"i").test(i)}catch{return!1}default:return!1}}function ae(i){if(!i||!i.trim())return[];let e=i.trim();if(e.startsWith("["))try{let n=JSON.parse(e);if(Array.isArray(n))return n.map(String)}catch{return[]}return e.split(",").map(n=>n.trim()).filter(Boolean)}var le=i=>i.toLowerCase()!=="false"&&i!=="0";function ue(i,e){let n=Le(i.operator),o=e.filter(a=>a!==""),s=()=>o.flatMap(a=>a.split(",").map(g=>g.trim()).filter(Boolean));switch(n){case"exists":case"not_empty":return o.length>0;case"not_exists":case"empty":return o.length===0;case"ne":return!o.some(a=>te(a,"eq",i.value));case"not_contains":return!o.some(a=>te(a,"contains",i.value));case"in":{let a=ae(i.value);return s().some(g=>a.some(m=>B(g,m)))}case"not_in":{let a=ae(i.value);return!s().some(g=>a.some(m=>B(g,m)))}case"true":return o.some(le);case"false":return!o.some(le);case void 0:return!1;default:return o.some(a=>te(a,n,i.value))}}var Ie=`
2
+ .oluso-journey {
3
+ --oluso-accent: #4f46e5;
4
+ --oluso-accent-contrast: #ffffff;
5
+ --oluso-fg: #111827;
6
+ --oluso-muted: #6b7280;
7
+ --oluso-bg: #ffffff;
8
+ --oluso-field-bg: #ffffff;
9
+ --oluso-border: #d1d5db;
10
+ --oluso-danger: #b91c1c;
11
+ --oluso-danger-bg: #fef2f2;
12
+ --oluso-notice-bg: #eff6ff;
13
+ --oluso-notice: #1d4ed8;
14
+ --oluso-radius: 8px;
15
+ --oluso-gap: 14px;
16
+ --oluso-font: inherit;
17
+ font-family: var(--oluso-font);
18
+ color: var(--oluso-fg);
19
+ font-size: 15px;
20
+ line-height: 1.5;
21
+ }
22
+ .oluso-journey[data-theme="dark"] {
23
+ --oluso-fg: #f3f4f6;
24
+ --oluso-muted: #9ca3af;
25
+ --oluso-bg: #111827;
26
+ --oluso-field-bg: #1f2937;
27
+ --oluso-border: #374151;
28
+ --oluso-danger: #fca5a5;
29
+ --oluso-danger-bg: rgba(185, 28, 28, 0.15);
30
+ --oluso-notice-bg: rgba(59, 130, 246, 0.15);
31
+ --oluso-notice: #93c5fd;
32
+ }
33
+ @media (prefers-color-scheme: dark) {
34
+ .oluso-journey[data-theme="auto"] {
35
+ --oluso-fg: #f3f4f6;
36
+ --oluso-muted: #9ca3af;
37
+ --oluso-bg: #111827;
38
+ --oluso-field-bg: #1f2937;
39
+ --oluso-border: #374151;
40
+ --oluso-danger: #fca5a5;
41
+ --oluso-danger-bg: rgba(185, 28, 28, 0.15);
42
+ --oluso-notice-bg: rgba(59, 130, 246, 0.15);
43
+ --oluso-notice: #93c5fd;
44
+ }
45
+ }
46
+ .oluso-journey *, .oluso-journey *::before, .oluso-journey *::after { box-sizing: border-box; }
47
+ .oluso-journey__form { display: flex; flex-direction: column; gap: var(--oluso-gap); margin: 0; }
48
+ .oluso-journey__title { font-size: 1.25em; font-weight: 600; margin: 0; }
49
+ .oluso-journey__description { color: var(--oluso-muted); margin: 0; white-space: pre-line; }
50
+ .oluso-journey__alert { border-radius: var(--oluso-radius); padding: 10px 12px; margin: 0; }
51
+ .oluso-journey__alert--error { background: var(--oluso-danger-bg); color: var(--oluso-danger); }
52
+ .oluso-journey__alert--notice { background: var(--oluso-notice-bg); color: var(--oluso-notice); }
53
+ .oluso-journey__group { display: flex; flex-direction: column; gap: var(--oluso-gap); border: 0; margin: 0; padding: 0; }
54
+ .oluso-journey__field { display: flex; flex-direction: column; gap: 6px; }
55
+ .oluso-journey__field[hidden] { display: none; }
56
+ .oluso-journey__label { font-weight: 500; }
57
+ .oluso-journey__required { color: var(--oluso-danger); margin-left: 2px; }
58
+ .oluso-journey__input, .oluso-journey__select, .oluso-journey__textarea {
59
+ width: 100%; font: inherit; color: var(--oluso-fg); background: var(--oluso-field-bg);
60
+ border: 1px solid var(--oluso-border); border-radius: var(--oluso-radius); padding: 9px 11px; min-height: 40px;
61
+ }
62
+ .oluso-journey__input:focus, .oluso-journey__select:focus, .oluso-journey__textarea:focus {
63
+ outline: 2px solid var(--oluso-accent); outline-offset: 1px; border-color: transparent;
64
+ }
65
+ .oluso-journey__input[aria-invalid="true"], .oluso-journey__select[aria-invalid="true"], .oluso-journey__textarea[aria-invalid="true"] {
66
+ border-color: var(--oluso-danger);
67
+ }
68
+ .oluso-journey__input--otp { letter-spacing: 0.4em; font-variant-numeric: tabular-nums; text-align: center; font-size: 1.2em; }
69
+ .oluso-journey__phone { display: flex; gap: 8px; }
70
+ .oluso-journey__phone .oluso-journey__select { width: auto; max-width: 45%; }
71
+ .oluso-journey__choices { display: flex; flex-direction: column; gap: 8px; }
72
+ .oluso-journey__choice { display: flex; gap: 10px; align-items: flex-start; cursor: pointer; }
73
+ .oluso-journey__choice input { margin-top: 3px; accent-color: var(--oluso-accent); }
74
+ .oluso-journey__choice-description { display: block; color: var(--oluso-muted); font-size: 0.9em; }
75
+ .oluso-journey__help, .oluso-journey__hint { color: var(--oluso-muted); font-size: 0.875em; margin: 0; }
76
+ .oluso-journey__error { color: var(--oluso-danger); font-size: 0.875em; margin: 0; }
77
+ .oluso-journey__content { margin: 0; white-space: pre-line; }
78
+ .oluso-journey__actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
79
+ .oluso-journey__button {
80
+ font: inherit; font-weight: 500; border-radius: var(--oluso-radius); padding: 9px 16px; min-height: 40px; cursor: pointer;
81
+ border: 1px solid var(--oluso-border); background: var(--oluso-field-bg); color: var(--oluso-fg);
82
+ }
83
+ .oluso-journey__button--primary { background: var(--oluso-accent); color: var(--oluso-accent-contrast); border-color: var(--oluso-accent); }
84
+ .oluso-journey__button--primary:only-child, .oluso-journey__actions--stacked .oluso-journey__button--primary { flex: 1 1 auto; }
85
+ .oluso-journey__button--link { background: none; border: 0; color: var(--oluso-accent); padding: 4px 0; min-height: 0; }
86
+ .oluso-journey__button--cancel { background: none; }
87
+ .oluso-journey__button:disabled { opacity: 0.6; cursor: progress; }
88
+ .oluso-journey__enter { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
89
+ .oluso-journey__action-line { display: flex; flex-wrap: wrap; gap: 6px; align-items: baseline; margin: 0; }
90
+ .oluso-journey__links { display: flex; flex-wrap: wrap; gap: 12px; font-size: 0.9em; }
91
+ .oluso-journey__links a { color: var(--oluso-accent); }
92
+ .oluso-journey__qr { display: flex; flex-direction: column; align-items: center; gap: 8px; }
93
+ .oluso-journey__qr img { width: 180px; height: 180px; background: #fff; padding: 8px; border-radius: var(--oluso-radius); }
94
+ .oluso-journey__code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; word-break: break-all; }
95
+ .oluso-journey__codes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; margin: 0; padding: 0; list-style: none; }
96
+ .oluso-journey__codes li { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; padding: 6px 8px; border: 1px solid var(--oluso-border); border-radius: 6px; text-align: center; }
97
+ .oluso-journey__status { color: var(--oluso-muted); text-align: center; padding: 16px 0; }
98
+ .oluso-journey__done { text-align: center; padding: 8px 0; }
99
+ `,ce=!1;function de(){if(ce||typeof document>"u")return;let i=document.createElement("style");i.setAttribute("data-oluso-journey",""),i.textContent=Ie,document.head.appendChild(i),ce=!0}function W(i){let e=i.replace(/-/g,"+").replace(/_/g,"/"),n=e+"=".repeat((4-e.length%4)%4),o=atob(n),s=new Uint8Array(o.length);for(let a=0;a<o.length;a++)s[a]=o.charCodeAt(a);return s.buffer}function M(i){if(!i)return null;let e=new Uint8Array(i),n="";for(let o=0;o<e.length;o++)n+=String.fromCharCode(e[o]);return btoa(n).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function pe(i){if(Array.isArray(i))return i.map(e=>({type:e.type??"public-key",id:W(String(e.id)),transports:e.transports}))}function Je(i){return{...i,challenge:W(String(i.challenge)),allowCredentials:pe(i.allowCredentials)}}function Me(i){let e=i.user??{};return{...i,challenge:W(String(i.challenge)),user:{...e,id:W(String(e.id))},excludeCredentials:pe(i.excludeCredentials)}}async function he(i){let e=await navigator.credentials.get({publicKey:Je(i)});if(!e)throw new Error("No passkey was chosen");let n=e.response;return JSON.stringify({id:e.id,rawId:M(e.rawId),type:e.type,response:{clientDataJSON:M(n.clientDataJSON),authenticatorData:M(n.authenticatorData),signature:M(n.signature),userHandle:M(n.userHandle)},authenticatorAttachment:e.authenticatorAttachment??null})}async function ge(i){let e=await navigator.credentials.create({publicKey:Me(i)});if(!e)throw new Error("No passkey was created");let n=e.response;return JSON.stringify({id:e.id,rawId:M(e.rawId),type:e.type,response:{clientDataJSON:M(n.clientDataJSON),attestationObject:M(n.attestationObject),transports:typeof n.getTransports=="function"?n.getTransports():void 0},authenticatorAttachment:e.authenticatorAttachment??null})}var $e={loading:"Loading\u2026",completed:"All done. Thank you.",failed:"Something went wrong. Please try again.",expired:"This session has expired. Please start again.",restart:"Start again",takePhoto:"Take a photo",copy:"Copy",copied:"Copied",passkey:"Use your passkey",retry:"Try again",waiting:"Waiting\u2026",unavailable:"This step can\u2019t be shown here."};function d(i,e,n){let o=document.createElement(i);return e&&(o.className=e),n!==void 0&&(o.textContent=n),o}var Fe=0;function fe(i,e){let n={...$e,...e.labels},o=e.client,s=`oluso-j${++Fe}`,a,g=!1,m=[];e.unstyled||de();let f=d("div","oluso-journey");f.setAttribute("data-theme",e.theme??"auto"),i.appendChild(f);let x=()=>{m.forEach(t=>window.clearInterval(t)),m=[]},L=t=>{f.replaceChildren(d("p","oluso-journey__status",t))},C=t=>{let c=t instanceof Error?t:new Error(String(t));return e.onError?.(c,a),c},U=()=>!!(e.slug||e.start),P=async()=>{x(),L(n.loading);try{let t=e.start?await e.start():e.slug?await o.startJourney(e.slug,e.data):e.session;if(!t)throw new Error("mountJourney needs a slug, a session or a start function");await w(t)}catch(t){F(C(t).message)}},w=async t=>{if(!g){if(x(),a=t,e.onStep?.(t),t.completed){if(t.redirectUrl){await e.onComplete?.(t),I(t.redirectUrl,t);return}if(e.showCompletion!==!1){let c=d("div","oluso-journey__done");c.appendChild(d("p","oluso-journey__content",t.message||n.completed)),f.replaceChildren(c)}else f.replaceChildren();await e.onComplete?.(t);return}if(t.status!=="in_progress"){let c=t.status==="expired"?n.expired:t.errorDescription||n.failed;C(new Error(c)),F(c);return}if(t.redirectUrl){I(t.redirectUrl,t);return}t.step?.form?A(t.step.form):t.step?.html?Se(t.step.html):F(n.unavailable)}},I=(t,c)=>{e.onRedirect?e.onRedirect(t,c):window.location.assign(t)},F=t=>{let c=d("div","oluso-journey__form");if(c.appendChild(d("p","oluso-journey__alert oluso-journey__alert--error",t)),U()){let l=d("button","oluso-journey__button oluso-journey__button--primary",n.restart);l.type="button",l.addEventListener("click",()=>{P()});let y=d("div","oluso-journey__actions");y.appendChild(l),c.appendChild(y)}f.replaceChildren(c)},$=async(t,c)=>{if(!a)return;let l=await o.submitStepForm(a.sessionId,t,c);await w(l)},T=(t,c)=>{t.setAttribute("aria-busy",String(c)),t.querySelectorAll("button").forEach(l=>l.disabled=c)},H=async(t,c,l)=>{let y=c?.postsFields===!1?new FormData:new FormData(t);if(c?.name&&y.append(c.name,c.value??""),c?.values)for(let[_,u]of Object.entries(c.values))y.append(_,u);if(l)for(let[_,u]of Object.entries(l))y.set(_,u);T(t,!0);try{await $(y)}catch(_){T(t,!1);let u=C(_).message,r=t.querySelector("[data-oluso-request-error]");r||(r=d("p","oluso-journey__alert oluso-journey__alert--error"),r.setAttribute("data-oluso-request-error",""),r.setAttribute("role","alert"),t.prepend(r)),r.textContent=u}},A=t=>{let c=d("form","oluso-journey__form");if(t.title&&c.appendChild(d("h2","oluso-journey__title",t.title)),t.description&&c.appendChild(d("p","oluso-journey__description",t.description)),t.error){let u=d("p","oluso-journey__alert oluso-journey__alert--error",t.error);u.setAttribute("role","alert"),c.appendChild(u)}if(t.notice){let u=d("p","oluso-journey__alert oluso-journey__alert--notice",t.notice);u.setAttribute("role","status"),c.appendChild(u)}let l=[];for(let u of t.fields){let r=Q(u);r&&(c.appendChild(r),(u.showWhen||u.showWhenAll?.length)&&l.push({field:u,wrapper:r}))}if(t.widget){let u=xe(t.widget,c);u&&c.appendChild(u)}if(t.links.length>0){let u=d("div","oluso-journey__links");for(let r of t.links){let h=d("a",void 0,r.label);h.href=r.url,h.target="_blank",h.rel="noopener noreferrer",u.appendChild(h)}c.appendChild(u)}if(t.actions.length>0){let u=d("div","oluso-journey__actions"),r=t.actions.findIndex(p=>p.kind==="primary");if(r>=0){let p=d("button","oluso-journey__enter");p.type="submit",p.tabIndex=-1,p.setAttribute("aria-hidden","true"),p.dataset.olusoAction=String(r),c.prepend(p)}let h=[];t.actions.forEach((p,b)=>{let v=d("button",`oluso-journey__button oluso-journey__button--${p.kind}`,p.label);if(v.type="submit",v.formNoValidate=p.skipValidation||p.postsFields===!1,v.dataset.olusoAction=String(b),p.description){let k=d("p","oluso-journey__action-line");k.appendChild(d("span","oluso-journey__help",p.description)),k.appendChild(v),h.push(k)}else u.appendChild(v)}),u.childElementCount>0&&c.appendChild(u),h.forEach(p=>c.appendChild(p))}let y=()=>{for(let{field:u,wrapper:r}of l){let p=[...u.showWhen?[u.showWhen]:[],...u.showWhenAll??[]].every(b=>ue(b,qe(c.elements.namedItem(b.field))));r.hidden=!p,r.querySelectorAll("input, select, textarea").forEach(b=>{b.disabled=!p||b.dataset.olusoReadonly==="true"})}};c.addEventListener("input",u=>{y();let h=u.target.closest(".oluso-journey__field");h?.querySelectorAll('[aria-invalid="true"]').forEach(p=>p.removeAttribute("aria-invalid")),h?.querySelector(".oluso-journey__error")?.remove()}),c.addEventListener("change",y),y(),c.addEventListener("submit",u=>{u.preventDefault();let r=u.submitter,h=r?.dataset.olusoAction,p=h!==void 0?t.actions[Number(h)]:t.actions.find(b=>b.kind==="primary");if(p?.confirm&&r&&r.dataset.olusoConfirming!=="true"){r.dataset.olusoConfirming="true",r.textContent=p.confirm,r.setAttribute("aria-live","polite");return}H(c,p)}),f.replaceChildren(c),(c.querySelector("[autofocus]")??c.querySelector("input:not([type=hidden]):not([disabled]), select, textarea"))?.focus({preventScroll:!0})},Q=t=>{let c=`${s}-${t.name}`;if(t.type==="hidden"){let r=d("input");return r.type="hidden",r.name=t.name,r.value=t.value??"",r}let l=d("div","oluso-journey__field");if(t.group&&(l.dataset.group=t.group),t.type==="content")return t.label&&l.appendChild(d("p","oluso-journey__label",t.label)),l.appendChild(d("p","oluso-journey__content",t.value??"")),l;let y=()=>{if(!t.label)return;let r=d("label","oluso-journey__label",t.label);if(r.htmlFor=c,t.required){let h=d("span","oluso-journey__required","*");h.setAttribute("aria-hidden","true"),r.appendChild(h)}l.appendChild(r)},_=[],u=r=>{r.id=c,r.name=t.name,r.required=t.required,t.readOnly&&(r instanceof HTMLSelectElement?r.disabled=!0:r.readOnly=!0,r.dataset.olusoReadonly=String(r instanceof HTMLSelectElement)),t.autofocus&&(r.autofocus=!0),t.autocomplete&&r.setAttribute("autocomplete",t.autocomplete),t.error&&r.setAttribute("aria-invalid","true")};switch(t.type){case"textarea":{y();let r=d("textarea","oluso-journey__textarea");u(r),r.value=t.value??"",t.placeholder&&(r.placeholder=t.placeholder),t.rows&&(r.rows=t.rows),t.minLength&&(r.minLength=t.minLength),t.maxLength&&(r.maxLength=t.maxLength),l.appendChild(r);break}case"select":{y();let r=d("select","oluso-journey__select");u(r);let h=d("option",void 0,t.placeholder??"");h.value="",r.appendChild(h);for(let p of t.options??[]){let b=d("option",void 0,p.label);b.value=p.value,b.disabled=p.disabled,b.selected=p.value===t.value,r.appendChild(b)}l.appendChild(r);break}case"radio":{let r=d("fieldset","oluso-journey__group");if(t.label){let p=d("legend","oluso-journey__label",t.label);t.required&&p.appendChild(d("span","oluso-journey__required","*")),r.appendChild(p)}let h=d("div","oluso-journey__choices");(t.options??[]).forEach((p,b)=>{let v=d("label","oluso-journey__choice"),k=d("input");k.type="radio",k.name=t.name,k.value=p.value,k.id=`${c}-${b}`,k.required=t.required,k.disabled=p.disabled||t.readOnly,k.checked=p.value===t.value;let S=d("span",void 0,p.label);p.description&&S.appendChild(d("span","oluso-journey__choice-description",p.description)),v.append(k,S),h.appendChild(v)}),r.appendChild(h),l.appendChild(r);break}case"checkbox":{t.placeholder&&y();let r=d("label","oluso-journey__choice"),h=d("input");h.type="checkbox",h.value="true",u(h),h.checked=t.value==="true",t.readOnly&&(h.setAttribute("aria-readonly","true"),h.addEventListener("click",b=>b.preventDefault()));let p=d("span",void 0,t.placeholder??t.label??"");!t.placeholder&&t.required&&p.appendChild(d("span","oluso-journey__required","*")),r.append(h,p),l.appendChild(r);break}case"file":{y();let r=d("input","oluso-journey__input");if(r.type="file",u(r),r.readOnly=!1,r.disabled=t.readOnly,t.accept&&(r.accept=t.accept),r.multiple=(t.maxFiles??1)>1,r.required=t.required&&!t.capture,l.appendChild(r),t.capture&&!t.readOnly){let h=d("label","oluso-journey__hint",n.takePhoto);h.htmlFor=`${c}-camera`;let p=d("input","oluso-journey__input");p.type="file",p.id=`${c}-camera`,p.name=t.name,p.accept="image/*",p.setAttribute("capture",t.capture),l.append(h,p)}break}case"tel":{if(y(),t.countries&&t.countries.length>0){let r=d("div","oluso-journey__phone"),h=d("select","oluso-journey__select");h.name=`${t.name}__country`,h.setAttribute("aria-label",t.label??t.name),h.disabled=t.readOnly;for(let b of t.countries){let v=d("option",void 0,`${b.flag?b.flag+" ":""}${b.name} (${b.dialCode})`);v.value=b.code,v.selected=b.code===t.country,h.appendChild(v)}let p=d("input","oluso-journey__input");p.type="tel",p.inputMode="tel",u(p),p.value=t.value??"",t.placeholder&&(p.placeholder=t.placeholder),r.append(h,p),l.appendChild(r)}else{let r=ie(t,"tel");u(r),l.appendChild(r)}break}case"otp":{y();let r=d("input","oluso-journey__input oluso-journey__input--otp");r.type="text",r.inputMode="numeric",u(r),r.setAttribute("autocomplete",t.autocomplete??"one-time-code"),t.maxLength&&(r.maxLength=t.maxLength,r.minLength=t.minLength??t.maxLength),r.pattern=t.pattern??"[0-9]*",r.value=t.value??"",l.appendChild(r);break}default:{y();let h=ie(t,["text","email","password","number","date","url","tel"].includes(t.type)?t.type:"text");u(h),l.appendChild(h)}}if(t.description){let r=d("p","oluso-journey__help",t.description);r.id=`${c}-help`,_.push(r.id),l.appendChild(r)}if(t.hint){let r=d("p","oluso-journey__hint",t.hint);r.id=`${c}-hint`,_.push(r.id),l.appendChild(r)}if(t.error){let r=d("p","oluso-journey__error",t.error);r.id=`${c}-error`,_.push(r.id),l.appendChild(r)}return _.length>0&&Array.from(l.querySelectorAll("[id]")).find(r=>r.id===c)?.setAttribute("aria-describedby",_.join(" ")),l},ie=(t,c)=>{let l=d("input","oluso-journey__input");return l.type=c,l.value=t.value??"",t.placeholder&&(l.placeholder=t.placeholder),t.pattern&&(l.pattern=t.pattern),t.patternError&&(l.title=t.patternError,l.addEventListener("invalid",()=>{l.validity.patternMismatch&&l.setCustomValidity(t.patternError)}),l.addEventListener("input",()=>l.setCustomValidity(""))),t.minLength&&(l.minLength=t.minLength),t.maxLength&&(l.maxLength=t.maxLength),t.min&&(l.min=t.min),t.max&&(l.max=t.max),c==="number"&&(l.step="any"),l},xe=(t,c)=>{let l=t.data??{},y=d("div","oluso-journey__widget"),_=u=>{if(!t.resultField)return;let r=Array.from(c.querySelectorAll("input[type=hidden]")).find(h=>h.name===t.resultField)??null;r||(r=d("input"),r.type="hidden",r.name=t.resultField,c.appendChild(r)),r.value=u};switch(t.type){case"webauthn_get":case"webauthn_create":{let u=d("button","oluso-journey__button oluso-journey__button--primary",t.submit?.label??n.passkey);u.type="button";let r=async()=>{u.disabled=!0;try{let h=await Ce(l),p=h.publicKey,b=h.extra,v=t.type==="webauthn_get"?await he(p):await ge(p);_(v);let k=l.credentialName;if(k?.field){let S=JSON.parse(v).authenticatorAttachment,J=S==="platform"?k.platform:S==="cross-platform"?k.crossPlatform:k.other;(b??(b={}))[k.field]=J??""}await H(c,t.submit,b)}catch(h){u.disabled=!1,u.textContent=n.retry,e.onError?.(h instanceof Error?h:new Error(String(h)),a)}};return u.addEventListener("click",()=>{r()}),y.appendChild(u),typeof PublicKeyCredential<"u"&&queueMicrotask(()=>{r()}),y}case"verification_connect":{let u=l.options??{},r=typeof l.referenceOption=="string"?u[l.referenceOption]:void 0,h=typeof l.referenceField=="string"?l.referenceField:"reference_id",p=async S=>{let J=new FormData;S&&J.set(h,r==null?"":String(r)),T(c,!0);try{await $(J,"callback")}catch(je){T(c,!1),C(je)}},b=async()=>{await He(String(l.scriptUrl));let S=window[typeof l.global=="string"?l.global:"Connect"];if(!S)throw new Error("The verification widget could not be loaded");let J=new S({...u,onSuccess:()=>{p(!0)},onError:()=>{p(!1)},onClose:()=>{}});return J.setup?.(),J.open(),J},v,k=()=>{if(v){v.then(S=>S.open());return}v=b(),v.catch(S=>{v=void 0,C(S)})};if(t.submit){let S=d("button",`oluso-journey__button oluso-journey__button--${t.submit.kind}`,t.submit.label);S.type="button",S.addEventListener("click",k),y.appendChild(S)}return k(),y}case"captcha":{let u=d("div","oluso-journey__captcha");return y.appendChild(u),De(u,l,r=>{_(r),t.submit&&H(c,t.submit)}).catch(r=>e.onError?.(r instanceof Error?r:new Error(String(r)),a)),y}case"qr":{let u=d("div","oluso-journey__qr");if(typeof l.image=="string"){let r=d("img");r.src=l.image,r.alt="",u.appendChild(r)}return typeof l.secret=="string"?(typeof l.secretLabel=="string"&&u.appendChild(d("span","oluso-journey__help",l.secretLabel)),u.appendChild(d("code","oluso-journey__code",l.secret))):typeof l.value=="string"&&typeof l.image!="string"&&u.appendChild(d("code","oluso-journey__code",l.value)),y.appendChild(u),y}case"codes":{let u=Array.isArray(l.codes)?l.codes.map(String):[],r=d("ul","oluso-journey__codes");u.forEach(p=>r.appendChild(d("li",void 0,p)));let h=d("button","oluso-journey__button",n.copy);return h.type="button",h.addEventListener("click",()=>{navigator.clipboard?.writeText(u.join(`
100
+ `)).then(()=>h.textContent=n.copied)}),y.append(r,h),y}case"poll":{let u=Math.max(2,Number(l.intervalSeconds)||5),r=Number(l.maxSeconds)>0?Date.now()+Number(l.maxSeconds)*1e3:1/0,h=a?.currentStep;return m.push(window.setInterval(()=>{if(Date.now()>r){x();return}!a||document.hidden||o.getSession(a.sessionId).then(async p=>{(p.status!=="in_progress"||p.currentStep!==h)&&(x(),await $(new FormData,"init"))}).catch(()=>{})},u*1e3)),null}default:return null}},Ce=async t=>{if(t.publicKey)return{publicKey:t.publicKey,extra:void 0};let c=String(t.optionsUrl),l=/^https?:/i.test(c)?c:`${o.serverUrl}${c.startsWith("/")?"":"/"}${c}`,y=String(t.optionsMethod??"POST").toUpperCase(),_=await fetch(l,{method:y,headers:{"Content-Type":"application/json"},body:y==="GET"?void 0:JSON.stringify(t.optionsBody??{}),credentials:"include"});if(!_.ok)throw new Error(n.failed);let u=await _.json(),r={};return typeof t.idProperty=="string"&&typeof t.idField=="string"&&u[t.idProperty]!=null&&(r[t.idField]=String(u[t.idProperty])),{publicKey:u.options??u,extra:r}},Se=t=>{let c=d("div","oluso-journey__html");c.innerHTML=t,c.querySelectorAll("script").forEach(l=>l.remove()),c.addEventListener("submit",l=>{let y=l.target;l.preventDefault();let _=l.submitter,u=new FormData(y);_?.name&&u.append(_.name,_.value),u.delete("__RequestVerificationToken"),T(y,!0),$(u).catch(r=>{T(y,!1),C(r)})}),f.replaceChildren(c)};return e.session?w(e.session):P(),{get session(){return a},restart:P,destroy(){g=!0,x(),f.remove()}}}function qe(i){return i?(i instanceof RadioNodeList?Array.from(i):[i]).flatMap(n=>{let o=n;return o.disabled?[]:o.type==="checkbox"||o.type==="radio"?o.checked?[o.value]:[]:o instanceof HTMLSelectElement&&o.multiple?Array.from(o.selectedOptions).map(s=>s.value):[o.value]}):[]}var ne=new Map;function He(i){let e=ne.get(i);return e||(e=new Promise((n,o)=>{let s=document.createElement("script");s.src=i,s.async=!0,s.onload=()=>n(),s.onerror=()=>{ne.delete(i),o(new Error("A script the step needs could not be loaded"))},document.head.appendChild(s)}),ne.set(i,e)),e}var Ne={recaptcha:{src:"https://www.google.com/recaptcha/api.js?render=explicit&onload=",global:"grecaptcha"},hcaptcha:{src:"https://js.hcaptcha.com/1/api.js?render=explicit&onload=",global:"hcaptcha"},turnstile:{src:"https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit&onload=",global:"turnstile"}};async function De(i,e,n){let o=String(e.provider??"recaptcha").toLowerCase(),s=Ne[o];if(!s)throw new Error(`Captcha provider '${o}' isn't supported`);let a=window;if(!a[s.global]){let f=`__olusoCaptcha${Date.now()}`;await new Promise((x,L)=>{a[f]=()=>x();let C=document.createElement("script");C.src=s.src+f+(e.language?`&hl=${encodeURIComponent(String(e.language))}`:""),C.async=!0,C.onerror=()=>L(new Error("The captcha could not be loaded")),document.head.appendChild(C)})}let g=a[s.global],m=String(e.siteKey??"");if(o==="recaptcha"&&e.version==="v3"&&g.execute){g.ready?.(()=>{g.execute(m,{action:String(e.action??"submit")}).then(n)});return}g.render(i,{sitekey:m,theme:e.theme,size:e.size,action:e.action,callback:f=>n(f)})}var oe="oluso_auth_tokens",re=class{constructor(){this.tokens=null}getTokens(){return this.tokens&&Date.now()/1e3>=this.tokens.expiresAt&&(this.tokens=null),this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},se=class{constructor(e){this.store=e==="localStorage"?localStorage:sessionStorage}getTokens(){try{let e=this.store.getItem(oe);if(!e)return null;let n=JSON.parse(e);return Date.now()/1e3>=n.expiresAt?(this.clear(),null):n}catch{return null}}setTokens(e){this.store.setItem(oe,JSON.stringify(e))}clear(){this.store.removeItem(oe)}};function ye(i){return i==="memory"?new re:new se(i)}var V=class{constructor(e){this.user=null;this.resolvedEndpoints=null;this.discoveryPromise=null;this.journeyVerifiers=new Map;if(!e.serverUrl||!e.tenant||!e.clientId)throw new Error("serverUrl, tenant, and clientId are required");this.config={scopes:"openid profile email",signInJourney:"signin",signUpJourney:"signup",passwordResetJourney:"password-reset",storage:"memory",...e,serverUrl:e.serverUrl.replace(/\/$/,"")},this.storage=ye(this.config.storage);let n=this.storage.getTokens();n&&(this.user=this.parseIdToken(n.idToken))}async signIn(e){return e?this.executeJourney(this.config.signInJourney,e):this.openAuthModal("signin")}async signUp(e){return e?this.executeJourney(this.config.signUpJourney,e):this.openAuthModal("signup")}async signInWithPasskey(e){if(!window.PublicKeyCredential)return{success:!1,error:"WebAuthn is not supported in this browser"};let{verifier:n,challenge:o}=await this.generatePkce(),s=`${this.config.serverUrl}/connect/webauthn/assertion-options`,a=await fetch(s,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify({clientId:this.config.clientId,username:e?.username,scope:this.config.scopes,codeChallenge:o,codeChallengeMethod:"S256"})});if(!a.ok){let w=await a.json().catch(()=>({error_description:"Failed to get passkey options"}));return{success:!1,error:w.error_description||w.error}}let g=await a.json(),m={challenge:this.base64UrlDecode(g.challenge),timeout:g.timeout,rpId:g.rpId,userVerification:g.userVerification||"preferred",allowCredentials:g.allowCredentials?.map(w=>({type:w.type,id:this.base64UrlDecode(w.id),transports:w.transports}))},f;try{let w={publicKey:m,signal:e?.signal};e?.conditional&&(w.mediation="conditional"),f=await navigator.credentials.get(w)}catch(w){let I=w instanceof Error?w.message:"Passkey request failed";return w instanceof DOMException&&w.name==="AbortError"?{success:!1,error:"cancelled"}:w instanceof DOMException&&w.name==="NotAllowedError"?{success:!1,error:"cancelled"}:{success:!1,error:I}}if(!f)return{success:!1,error:"No credential returned"};let x=f.response,L=JSON.stringify({id:f.id,rawId:this.base64UrlEncode(new Uint8Array(f.rawId)),type:f.type,response:{clientDataJSON:this.base64UrlEncode(new Uint8Array(x.clientDataJSON)),authenticatorData:this.base64UrlEncode(new Uint8Array(x.authenticatorData)),signature:this.base64UrlEncode(new Uint8Array(x.signature)),userHandle:x.userHandle?this.base64UrlEncode(new Uint8Array(x.userHandle)):null}}),C=`${this.config.serverUrl}/connect/webauthn/assertion`,U=await fetch(C,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify({clientId:this.config.clientId,assertionId:g.assertionId,assertionResponse:L,codeChallenge:o,codeChallengeMethod:"S256",scope:this.config.scopes})});if(!U.ok){let w=await U.json().catch(()=>({error_description:"Passkey verification failed"}));return{success:!1,error:w.error_description||w.error}}let{code:P}=await U.json();return this.exchangeCodeForTokens(P,n,"postmessage")}async signInWithFedCM(e){if(!("IdentityCredential"in window))return{success:!1,error:"FedCM is not supported in this browser"};let{verifier:n,challenge:o}=await this.generatePkce();try{let s=await navigator.credentials.get({identity:{providers:[{configURL:`${this.config.serverUrl}/fedcm/config.json`,clientId:this.config.clientId,nonce:e?.nonce,loginHint:e?.loginHint,params:{code_challenge:o,code_challenge_method:"S256",scope:this.config.scopes}}]},mediation:e?.autoReauth?"optional":"required"});return s?.token?this.exchangeCodeForTokens(s.token,n,"fedcm"):{success:!1,error:"No credential returned from FedCM"}}catch(s){return s instanceof DOMException&&s.name==="AbortError"?{success:!1,error:"cancelled"}:s instanceof DOMException&&s.name==="NetworkError"?{success:!1,error:"FedCM network error \u2014 user may not be signed in to the identity provider"}:{success:!1,error:s instanceof Error?s.message:"FedCM request failed"}}}mountSignIn(e,n={}){let o=new z({serverUrl:this.config.serverUrl,tenant:this.config.tenant,apiKey:this.config.apiKey}),s="";return fe(e,{client:o,theme:n.theme,unstyled:n.unstyled,labels:n.labels,showCompletion:!1,onError:n.onError,onRedirect:n.onRedirect,start:async()=>{let a=await this.generatePkce();return s=a.verifier,o.startAuthJourney(n.journey??this.config.signInJourney,{clientId:this.config.clientId,codeChallenge:a.challenge,scope:this.config.scopes})},onComplete:async a=>{let g=a.code?await this.exchangeCodeForTokens(a.code,s,"postmessage"):{success:!1,error:a.errorDescription||a.error||"Authentication failed",code:a.error};n.onSignedIn?.(g)}})}async continueStep(e,n){let o=this.journeyVerifiers.get(e);if(!o)return{success:!1,error:"This journey was not started by this client",code:"invalid_session"};let s=`${this.config.serverUrl}/api/public/journeys/sessions/${encodeURIComponent(e)}/step`,a=await fetch(s,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify({data:n}),credentials:"include"});if(!a.ok){let g=await a.json().catch(()=>({message:"Step failed"}));return{success:!1,error:g.error_description||g.message,code:g.error||g.code}}return this.handleJourneyResult(await a.json(),o)}async getJourneyStep(e){let n=`${this.config.serverUrl}/api/public/journeys/${encodeURIComponent(e)}`,o=await fetch(n,{headers:this.buildHeaders(),credentials:"include"});if(!o.ok)return null;let s=await o.json();return{step:"initial",fields:s.fields||[],title:s.ui?.title||s.name,description:s.description}}async loginWithRedirect(e){let{verifier:n,challenge:o}=await this.generatePkce();sessionStorage.setItem("oluso_pkce_verifier",n),e?.state&&sessionStorage.setItem("oluso_auth_state",e.state);let s=await this.getEndpoints(),a=new URLSearchParams({response_type:"code",client_id:this.config.clientId,redirect_uri:this.config.redirectUri||window.location.origin+"/callback",scope:this.config.scopes,code_challenge:o,code_challenge_method:"S256",tenant:this.config.tenant});e?.prompt&&a.set("prompt",e.prompt),e?.state&&a.set("state",e.state),window.location.href=`${s.authorization}?${a}`}async handleCallback(e){let n=new URL(e||window.location.href),o=n.searchParams.get("code"),s=n.searchParams.get("error");if(s)return{success:!1,error:n.searchParams.get("error_description")||s,code:s};if(!o)return{success:!1,error:"No authorization code in callback"};let a=sessionStorage.getItem("oluso_pkce_verifier");return sessionStorage.removeItem("oluso_pkce_verifier"),a?this.exchangeCodeForTokens(o,a,this.config.redirectUri||window.location.origin+"/callback"):{success:!1,error:"PKCE verifier not found"}}getUser(){return this.user}isAuthenticated(){return this.user!==null&&this.storage.getTokens()!==null}getAccessToken(){return this.storage.getTokens()?.accessToken??null}hasRole(e){return this.user?.roles.includes(e)??!1}hasAnyRole(...e){return e.some(n=>this.hasRole(n))}hasPermission(e){return this.user?.permissions.includes(e)??!1}async refreshToken(){let e=this.storage.getTokens();if(!e?.refreshToken)return!1;let n=await this.getEndpoints(),o=await fetch(n.token,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"refresh_token",client_id:this.config.clientId,refresh_token:e.refreshToken})});if(!o.ok)return this.logout(),!1;let s=await o.json();return this.processTokenResponse(s),!0}logout(e){let n=this.storage.getTokens();if(this.storage.clear(),this.user=null,this.config.onAuthStateChange?.(null),e?.redirect&&n?.idToken)if(this.resolvedEndpoints?.endSession||this.config.endpoints?.endSession){let o=new URLSearchParams({id_token_hint:n.idToken,post_logout_redirect_uri:e.postLogoutRedirectUri||window.location.origin});window.location.href=`${this.resolvedEndpoints?.endSession||this.config.endpoints?.endSession}?${o}`}else this.getEndpoints().then(o=>{let s=new URLSearchParams({id_token_hint:n.idToken,post_logout_redirect_uri:e.postLogoutRedirectUri||window.location.origin});window.location.href=`${o.endSession}?${s}`})}async fetchUserInfo(){let e=this.getAccessToken();if(!e)return null;let n=await this.getEndpoints(),o=await fetch(n.userinfo,{headers:{Authorization:`Bearer ${e}`}});if(!o.ok)return null;let s=await o.json();return this.user=this.claimsToUser(s),this.config.onAuthStateChange?.(this.user),this.user}async openAuthModal(e){let{verifier:n,challenge:o}=await this.generatePkce(),s=e==="signin"?this.config.signInJourney:this.config.signUpJourney,a=new URLSearchParams({journey:s,client_id:this.config.clientId,origin:window.location.origin,code_challenge:o,code_challenge_method:"S256",scope:this.config.scopes}),g=`${this.config.serverUrl}/embed/auth?${a}`;return new Promise(m=>{let f=document.createElement("div");f.style.cssText="position:fixed;inset:0;background:rgba(0,0,0,0.6);backdrop-filter:blur(4px);z-index:99999;display:flex;align-items:center;justify-content:center;padding:24px;";let x=document.createElement("div");x.style.cssText="background:#fff;border-radius:16px;width:100%;max-width:420px;max-height:90vh;overflow:hidden;box-shadow:0 25px 50px -12px rgba(0,0,0,0.25);";let L=document.createElement("div");L.style.cssText="display:flex;justify-content:flex-end;padding:12px 16px 0;";let C=document.createElement("button");C.innerHTML="&times;",C.style.cssText="background:none;border:none;cursor:pointer;color:#9ca3af;font-size:20px;padding:4px;border-radius:6px;",L.appendChild(C);let U=document.createElement("iframe");U.src=g,U.allow="camera; microphone",U.style.cssText="border:none;width:100%;min-height:300px;";let P=document.createElement("div");P.style.cssText="display:none;text-align:center;padding:10px 0;font-size:11px;color:#9ca3af;border-top:1px solid #e5e7eb;font-family:-apple-system,BlinkMacSystemFont,sans-serif;",P.innerHTML='Powered by <a href="https://oluso.io" target="_blank" rel="noopener" style="color:#9ca3af;text-decoration:none;">Oluso</a>',x.appendChild(L),x.appendChild(U),x.appendChild(P),f.appendChild(x),document.body.appendChild(f),document.body.style.overflow="hidden";let w=()=>{window.removeEventListener("message",$),document.removeEventListener("keydown",F),document.body.style.overflow="",f.remove()},I=()=>{w(),m({success:!1,error:"cancelled"})};C.addEventListener("click",I),f.addEventListener("click",T=>{T.target===f&&I()});let F=T=>{T.key==="Escape"&&I()};document.addEventListener("keydown",F);let $=async T=>{let H=new URL(this.config.serverUrl).origin;if(T.origin!==H)return;let A=T.data;if(!(!A||typeof A!="object"))if(A.type==="oluso:auth:code"){w();let Q=await this.exchangeCodeForTokens(A.code,n,"postmessage");m(Q)}else A.type==="oluso:auth:error"?(w(),m({success:!1,error:A.error})):A.type==="oluso:auth:ready"?P.style.display=A.hideBranding?"none":"block":A.type==="oluso:auth:resize"&&typeof A.height=="number"&&(U.style.height=`${A.height}px`)};window.addEventListener("message",$)})}async getEndpoints(){if(this.config.endpoints?.authorization&&this.config.endpoints?.token){let e=this.config.serverUrl;return{authorization:this.config.endpoints.authorization,token:this.config.endpoints.token,userinfo:this.config.endpoints.userinfo||`${e}/connect/userinfo`,endSession:this.config.endpoints.endSession||`${e}/connect/endsession`,jwks:this.config.endpoints.jwks||`${e}/.well-known/openid-configuration/jwks`}}return this.resolvedEndpoints?this.resolvedEndpoints:(this.discoveryPromise||(this.discoveryPromise=this.discoverEndpoints()),this.resolvedEndpoints=await this.discoveryPromise,this.resolvedEndpoints)}async discoverEndpoints(){let e=this.config.serverUrl,n=`${e}/.well-known/openid-configuration`;try{let o=await fetch(n);if(!o.ok)return this.defaultEndpoints();let s=await o.json();return{authorization:s.authorization_endpoint||`${e}/connect/authorize`,token:s.token_endpoint||`${e}/connect/token`,userinfo:s.userinfo_endpoint||`${e}/connect/userinfo`,endSession:s.end_session_endpoint||`${e}/connect/endsession`,jwks:s.jwks_uri||`${e}/.well-known/openid-configuration/jwks`}}catch{return this.defaultEndpoints()}}defaultEndpoints(){let e=this.config.serverUrl;return{authorization:`${e}/connect/authorize`,token:`${e}/connect/token`,userinfo:`${e}/connect/userinfo`,endSession:`${e}/connect/endsession`,jwks:`${e}/.well-known/openid-configuration/jwks`}}async executeJourney(e,n){let{verifier:o,challenge:s}=await this.generatePkce(),a=`${this.config.serverUrl}/api/public/journeys/${encodeURIComponent(e)}/start`,g=await fetch(a,{method:"POST",headers:this.buildHeaders(),body:JSON.stringify({data:n,clientId:this.config.clientId,codeChallenge:s,codeChallengeMethod:"S256",scope:this.config.scopes}),credentials:"include"});if(!g.ok){let m=await g.json().catch(()=>({message:"Auth failed"}));return{success:!1,error:m.error_description||m.message,code:m.error||m.code}}return this.handleJourneyResult(await g.json(),o)}async handleJourneyResult(e,n){if(e.completed&&e.code)return this.journeyVerifiers.delete(e.sessionId),this.exchangeCodeForTokens(e.code,n,"postmessage");if(e.status==="in_progress"){this.journeyVerifiers.set(e.sessionId,n);let o=e.step?.model?.errorMessage??e.step?.model?.formError;return{success:!1,requiresStep:e.step?.type??e.currentStep,sessionId:e.sessionId,step:e.step,redirectUrl:e.redirectUrl,error:typeof o=="string"?o:void 0}}return this.journeyVerifiers.delete(e.sessionId),{success:!1,error:e.errorDescription||e.error||"Authentication failed",code:e.error}}processTokenResponse(e){let n={accessToken:e.access_token,idToken:e.id_token,refreshToken:e.refresh_token,expiresAt:Math.floor(Date.now()/1e3)+(e.expires_in||3600),tokenType:e.token_type||"Bearer",scope:e.scope};return this.storage.setTokens(n),this.user=this.parseIdToken(n.idToken),this.config.onAuthStateChange?.(this.user),{success:!0,user:this.user,tokens:n}}parseIdToken(e){if(!e)return null;try{let n=e.split(".");if(n.length!==3)return null;let o=JSON.parse(atob(n[1].replace(/-/g,"+").replace(/_/g,"/")));return this.claimsToUser(o)}catch{return null}}claimsToUser(e){return{sub:e.sub,name:e.name||e.preferred_username,email:e.email,emailVerified:e.email_verified,roles:this.parseArrayClaim(e.role||e.roles),permissions:this.parseArrayClaim(e.permission||e.permissions),tenantId:e.tenant_id,claims:e}}parseArrayClaim(e){return e?Array.isArray(e)?e.map(String):typeof e=="string"?[e]:[]:[]}buildHeaders(){let e={"Content-Type":"application/json","X-Tenant-ID":this.config.tenant};return this.config.apiKey&&(e["X-API-Key"]=this.config.apiKey),e}async generatePkce(){let e=new Uint8Array(32);crypto.getRandomValues(e);let n=this.base64UrlEncode(e),o=new TextEncoder,s=await crypto.subtle.digest("SHA-256",o.encode(n)),a=this.base64UrlEncode(new Uint8Array(s));return{verifier:n,challenge:a}}base64UrlEncode(e){let n="";for(let o=0;o<e.length;o++)n+=String.fromCharCode(e[o]);return btoa(n).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}base64UrlDecode(e){let n=e.replace(/-/g,"+").replace(/_/g,"/"),o="=".repeat((4-n.length%4)%4),s=atob(n+o),a=new Uint8Array(s.length);for(let g=0;g<s.length;g++)a[g]=s.charCodeAt(g);return a.buffer}async exchangeCodeForTokens(e,n,o){let s=await this.getEndpoints(),a=await fetch(s.token,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"authorization_code",client_id:this.config.clientId,code:e,redirect_uri:o,code_verifier:n})});if(!a.ok){let m=await a.json().catch(()=>({error_description:"Token exchange failed"}));return{success:!1,error:m.error_description||m.error}}let g=await a.json();return this.processTokenResponse(g)}};var ze=`
101
+ .oluso-auth-overlay {
102
+ position: fixed;
103
+ inset: 0;
104
+ background: rgba(0, 0, 0, 0.6);
105
+ backdrop-filter: blur(4px);
106
+ -webkit-backdrop-filter: blur(4px);
107
+ z-index: 99999;
108
+ display: flex;
109
+ align-items: center;
110
+ justify-content: center;
111
+ padding: 24px;
112
+ opacity: 0;
113
+ visibility: hidden;
114
+ transition: opacity 0.25s ease, visibility 0.25s ease;
115
+ }
116
+ .oluso-auth-overlay.oluso-active {
117
+ opacity: 1;
118
+ visibility: visible;
119
+ }
120
+ .oluso-auth-modal {
121
+ background: #ffffff;
122
+ border-radius: 16px;
123
+ width: 100%;
124
+ max-width: 420px;
125
+ max-height: 90vh;
126
+ overflow: hidden;
127
+ display: flex;
128
+ flex-direction: column;
129
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
130
+ transform: translateY(20px) scale(0.95);
131
+ transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
132
+ }
133
+ .oluso-active .oluso-auth-modal {
134
+ transform: translateY(0) scale(1);
135
+ }
136
+ .oluso-auth-header {
137
+ display: flex;
138
+ justify-content: flex-end;
139
+ padding: 12px 16px 0;
140
+ }
141
+ .oluso-auth-close {
142
+ background: none;
143
+ border: none;
144
+ cursor: pointer;
145
+ color: #9ca3af;
146
+ padding: 4px;
147
+ border-radius: 6px;
148
+ line-height: 1;
149
+ font-size: 20px;
150
+ transition: color 0.15s, background 0.15s;
151
+ }
152
+ .oluso-auth-close:hover {
153
+ color: #374151;
154
+ background: #f3f4f6;
155
+ }
156
+ .oluso-auth-iframe {
157
+ border: none;
158
+ width: 100%;
159
+ min-height: 300px;
160
+ transition: height 0.2s ease;
161
+ }
162
+ .oluso-auth-branding {
163
+ text-align: center;
164
+ padding: 10px 0;
165
+ font-size: 11px;
166
+ color: #9ca3af;
167
+ border-top: 1px solid #e5e7eb;
168
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
169
+ }
170
+ .oluso-auth-branding a {
171
+ color: #9ca3af;
172
+ text-decoration: none;
173
+ }
174
+ .oluso-auth-branding a:hover {
175
+ color: #6b7280;
176
+ }
177
+ @media (max-width: 480px) {
178
+ .oluso-auth-modal {
179
+ max-width: 100%;
180
+ max-height: 100vh;
181
+ height: 100%;
182
+ border-radius: 0;
183
+ }
184
+ .oluso-auth-overlay {
185
+ padding: 0;
186
+ }
187
+ }
188
+ @media (prefers-color-scheme: dark) {
189
+ .oluso-auth-modal {
190
+ background: #1f2937;
191
+ }
192
+ .oluso-auth-close:hover {
193
+ color: #e5e7eb;
194
+ background: #374151;
195
+ }
196
+ .oluso-auth-branding {
197
+ border-top-color: #374151;
198
+ color: #6b7280;
199
+ }
200
+ }
201
+ `,E=null,R=null,j=null,N=null,G=null,X=null,D=[],O=null,Y=null;function Ke(){N||(N=document.createElement("style"),N.id="oluso-auth-embed-styles",N.textContent=ze,document.head.appendChild(N))}function Be(){let i=new Uint8Array(32);crypto.getRandomValues(i);let e=me(i),n=new TextEncoder;return crypto.subtle.digest("SHA-256",n.encode(e)).then(o=>{let s=me(new Uint8Array(o));return{verifier:e,challenge:s}})}function me(i){let e="";for(let n=0;n<i.length;n++)e+=String.fromCharCode(i[n]);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}async function We(i){if(!E||!R||!Y)return{success:!1,error:"Not initialized"};let n=(await E.getEndpoints())?.token||`${R.serverUrl}/connect/token`,o=await fetch(n,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"authorization_code",client_id:R.clientId,code:i,redirect_uri:"postmessage",code_verifier:Y})});if(Y=null,!o.ok){let a=await o.json().catch(()=>({error_description:"Token exchange failed"}));return{success:!1,error:a.error_description||a.error}}let s=await o.json();return E.processTokenResponse(s)}function we(i){if(!R)return;let e=new URL(R.serverUrl).origin;if(i.origin!==e)return;let n=i.data;if(!(!n||typeof n!="object"))switch(n.type){case"oluso:auth:code":We(n.code).then(s=>{q(),s.success&&s.user&&D.forEach(a=>a(s.user)),O?.(s),O=null});break;case"oluso:auth:error":q();let o={success:!1,error:n.error};O?.(o),O=null;break;case"oluso:auth:ready":X&&(X.style.display=n.hideBranding?"none":"block");break;case"oluso:auth:resize":G&&typeof n.height=="number"&&(G.style.height=`${n.height}px`);break}}async function _e(i){if(!E||!R)return console.error("[OlusoAuth] Not initialized. Call OlusoAuth.init() first."),{success:!1,error:"Not initialized"};Ke();let{verifier:e,challenge:n}=await Be();Y=e;let o=i==="signin"?R.signInJourney||"signin":R.signUpJourney||"signup",s=new URLSearchParams({journey:o,client_id:R.clientId,origin:window.location.origin,code_challenge:n,code_challenge_method:"S256",scope:R.scopes||"openid profile email"}),a=`${R.serverUrl}/embed/auth?${s}`;j&&j.remove(),j=document.createElement("div"),j.className="oluso-auth-overlay",j.innerHTML=`
202
+ <div class="oluso-auth-modal">
203
+ <div class="oluso-auth-header">
204
+ <button class="oluso-auth-close" aria-label="Close">&times;</button>
205
+ </div>
206
+ <iframe class="oluso-auth-iframe" src="${a}" allow="camera; microphone"></iframe>
207
+ <div class="oluso-auth-branding" style="display:none">Powered by <a href="https://oluso.io" target="_blank" rel="noopener">Oluso</a></div>
208
+ </div>
209
+ `,document.body.appendChild(j),G=j.querySelector(".oluso-auth-iframe"),X=j.querySelector(".oluso-auth-branding"),j.querySelector(".oluso-auth-close")?.addEventListener("click",()=>{q(),O?.({success:!1,error:"cancelled"}),O=null}),j.addEventListener("click",f=>{f.target===j&&(q(),O?.({success:!1,error:"cancelled"}),O=null)});let m=f=>{f.key==="Escape"&&(q(),O?.({success:!1,error:"cancelled"}),O=null,document.removeEventListener("keydown",m))};return document.addEventListener("keydown",m),window.addEventListener("message",we),requestAnimationFrame(()=>{j.classList.add("oluso-active"),document.body.style.overflow="hidden"}),new Promise(f=>{O=f})}function q(){window.removeEventListener("message",we),j&&(j.classList.remove("oluso-active"),document.body.style.overflow="",setTimeout(()=>{j?.remove(),j=null,G=null,X=null},300))}function be(){document.addEventListener("click",i=>{let e=i.target.closest("[data-oluso-auth]");if(!e)return;i.preventDefault();let n=e.dataset.olusoAuth||"signin";n==="passkey"?ve():n==="fedcm"?ke():_e(n)})}typeof document<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",be):be());function Ve(i){R=i,E=new V(i)}function Ye(i="signin"){return _e(i)}function Ge(i){D.push(i);let e=E?.getUser()??null;e&&i(e)}function Xe(){return E?.getUser()??null}function Qe(i){return E?.hasRole(i)??!1}function Ze(i){return E?.hasPermission(i)??!1}function et(i){E?.logout(i),D.forEach(e=>e(null))}async function ve(i){if(!E)return{success:!1,error:"Not initialized. Call OlusoAuth.init() first."};let e=await E.signInWithPasskey(i);return e.success&&e.user&&D.forEach(n=>n(e.user)),e}async function ke(i){if(!E)return{success:!1,error:"Not initialized. Call OlusoAuth.init() first."};let e=await E.signInWithFedCM(i);return e.success&&e.user&&D.forEach(n=>n(e.user)),e}return Oe(tt);})();
210
+ //# sourceMappingURL=embed.global.js.map