authhero 0.105.0 → 0.106.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.
- package/dist/authhero.cjs +1 -1
- package/dist/authhero.mjs +1 -1
- package/package.json +1 -1
package/dist/authhero.cjs
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
}};
|
|
27
27
|
<\/script>
|
|
28
28
|
</body>
|
|
29
|
-
</html>`;return new Response(i,{headers:{"Content-Type":"text/html"}})}async function ty(t,e,n,r,i){var m,v,h;if(!n.redirect_uri)throw new z(400,{message:"Missing redirect_uri in authParams"});const[s]=await t.env.data.keys.list();if(!s)throw new z(500,{message:"No signing key found"});if(!((m=e.addons)!=null&&m.samlp))throw new z(400,{message:`SAML Addon is not enabled for client ${e.id}`});const{recipient:a,audience:c}=e.addons.samlp,l=n.state||"";if(!a||!l||!r||!n.state)throw new z(400,{message:"Missing recipient or inResponseTo"});const u=JSON.parse(n.state),p=new URL(n.redirect_uri),f=await ny(t,{issuer:t.env.ISSUER,audience:c||n.client_id,destination:p.toString(),inResponseTo:u.requestId,userId:((h=(v=r.app_metadata)==null?void 0:v.vimeo)==null?void 0:h.user_id)||r.user_id,email:r.email,sessionIndex:i,signature:{privateKeyPem:s.pkcs7,cert:s.cert,kid:s.kid}});return ey(p.toString(),f,u.relayState)}async function ny(t,e){const n=e.notBefore||new Date().toISOString(),r=e.notAfter||new Date(new Date(n).getTime()+10*60*1e3).toISOString(),i=e.issueInstant||n,s=e.sessionNotOnOrAfter||r,a=e.responseId||`_${xe()}`,c=e.assertionId||`_${xe()}`,l=[{"samlp:Response":[{"saml:Issuer":[{"#text":e.issuer}]},{"samlp:Status":[{"samlp:StatusCode":[],":@":{"@_Value":"urn:oasis:names:tc:SAML:2.0:status:Success"}}]},{"saml:Assertion":[{"saml:Issuer":[{"#text":e.issuer}]},{"saml:Subject":[{"saml:NameID":[{"#text":e.email}],":@":{"@_Format":"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"}},{"saml:SubjectConfirmation":[{"saml:SubjectConfirmationData":[],":@":{"@_InResponseTo":e.inResponseTo,"@_NotOnOrAfter":r,"@_Recipient":e.destination}}],":@":{"@_Method":"urn:oasis:names:tc:SAML:2.0:cm:bearer"}}]},{"saml:Conditions":[{"saml:AudienceRestriction":[{"saml:Audience":[{"#text":e.audience}]}]}],":@":{"@_NotBefore":n,"@_NotOnOrAfter":r}},{"saml:AuthnStatement":[{"saml:AuthnContext":[{"saml:AuthnContextClassRef":[{"#text":"urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified"}]}]}],":@":{"@_AuthnInstant":i,"@_SessionIndex":e.sessionIndex,"@_SessionNotOnOrAfter":s}},{"saml:AttributeStatement":[{"saml:Attribute":[{"saml:AttributeValue":[{"#text":e.userId}],":@":{"@_xmlns:xs":"http://www.w3.org/2001/XMLSchema","@_xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance","@_xsi:type":"xs:string"}}],":@":{"@_FriendlyName":"persistent","@_Name":"id","@_NameFormat":"urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"}},{"saml:Attribute":[{"saml:AttributeValue":[{"#text":e.email}],":@":{"@_xmlns:xs":"http://www.w3.org/2001/XMLSchema","@_xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance","@_xsi:type":"xs:string"}}],":@":{"@_Name":"email","@_NameFormat":"urn:oasis:names:tc:SAML:2.0:attrname-format:basic"}},{"saml:Attribute":[{"saml:AttributeValue":[{"#text":"manage-account"}],":@":{"@_xmlns:xs":"http://www.w3.org/2001/XMLSchema","@_xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance","@_xsi:type":"xs:string"}}],":@":{"@_Name":"Role","@_NameFormat":"urn:oasis:names:tc:SAML:2.0:attrname-format:basic"}},{"saml:Attribute":[{"saml:AttributeValue":[{"#text":"default-roles-master"}],":@":{"@_xmlns:xs":"http://www.w3.org/2001/XMLSchema","@_xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance","@_xsi:type":"xs:string"}}],":@":{"@_Name":"Role","@_NameFormat":"urn:oasis:names:tc:SAML:2.0:attrname-format:basic"}},{"saml:Attribute":[{"saml:AttributeValue":[{"#text":"offline_access"}],":@":{"@_xmlns:xs":"http://www.w3.org/2001/XMLSchema","@_xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance","@_xsi:type":"xs:string"}}],":@":{"@_Name":"Role","@_NameFormat":"urn:oasis:names:tc:SAML:2.0:attrname-format:basic"}},{"saml:Attribute":[{"saml:AttributeValue":[{"#text":"view-profile"}],":@":{"@_xmlns:xs":"http://www.w3.org/2001/XMLSchema","@_xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance","@_xsi:type":"xs:string"}}],":@":{"@_Name":"Role","@_NameFormat":"urn:oasis:names:tc:SAML:2.0:attrname-format:basic"}},{"saml:Attribute":[{"saml:AttributeValue":[{"#text":"uma_authorization"}],":@":{"@_xmlns:xs":"http://www.w3.org/2001/XMLSchema","@_xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance","@_xsi:type":"xs:string"}}],":@":{"@_Name":"Role","@_NameFormat":"urn:oasis:names:tc:SAML:2.0:attrname-format:basic"}},{"saml:Attribute":[{"saml:AttributeValue":[{"#text":"manage-account-links"}],":@":{"@_xmlns:xs":"http://www.w3.org/2001/XMLSchema","@_xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance","@_xsi:type":"xs:string"}}],":@":{"@_Name":"Role","@_NameFormat":"urn:oasis:names:tc:SAML:2.0:attrname-format:basic"}}]}],":@":{"@_xmlns":"urn:oasis:names:tc:SAML:2.0:assertion","@_ID":c,"@_IssueInstant":i,"@_Version":"2.0"}}],":@":{"@_xmlns:samlp":"urn:oasis:names:tc:SAML:2.0:protocol","@_xmlns:saml":"urn:oasis:names:tc:SAML:2.0:assertion","@_Destination":e.destination,"@_ID":a,"@_InResponseTo":e.inResponseTo,"@_IssueInstant":i,"@_Version":"2.0"}}];let p=new Q0.XMLBuilder({ignoreAttributes:!1,suppressEmptyNode:!0,preserveOrder:!0}).build(l);if(e.signature){const m=await fetch(t.env.SAML_SIGN_URL,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({xmlContent:p,privateKey:e.signature.privateKeyPem,publicCert:e.signature.cert})});if(!m.ok)throw new Error(`Failed to sign SAML response: ${m.status}`);p=await m.text()}return e.encode===!1?p:btoa(p)}var ry={deno:"Deno",bun:"Bun",workerd:"Cloudflare-Workers",node:"Node.js"},iy=()=>{var n,r;const t=globalThis;if(typeof navigator<"u"&&typeof navigator.userAgent=="string"){for(const[i,s]of Object.entries(ry))if(sy(s))return i}return typeof(t==null?void 0:t.EdgeRuntime)=="string"?"edge-light":(t==null?void 0:t.fastly)!==void 0?"fastly":((r=(n=t==null?void 0:t.process)==null?void 0:n.release)==null?void 0:r.name)==="node"?"node":"other"},sy=t=>navigator.userAgent.startsWith(t);function nt(t,e){iy()==="workerd"&&t.executionCtx.waitUntil(e)}function on(t){var e,n,r;return{auth0Client:(e=t.query("auth0Client"))==null?void 0:e.slice(0,255),ip:(n=t.header("x-real-ip"))==null?void 0:n.slice(0,45),useragent:(r=t.header("user-agent"))==null?void 0:r.slice(0,512)}}const Ju=["sub","iss","aud","exp","nbf","iat","jti"];async function to(t,e){var _,w;const{authParams:n,user:r,client:i,session_id:s}=e,c=(await t.env.data.keys.list()).filter(S=>!S.revoked_at||new Date(S.revoked_at)>new Date),l=c[c.length-1];if(!(l!=null&&l.pkcs7))throw new z(500,{message:"No signing key available"});const u=A_(l.pkcs7),p={aud:n.audience||"default",scope:n.scope||"",sub:(r==null?void 0:r.user_id)||n.client_id,iss:t.var.custom_domain?`https://${t.var.custom_domain}`:t.env.ISSUER,tenant_id:t.var.tenant_id,sid:s},f=r&&((_=n.scope)!=null&&_.split(" ").includes("openid"))?{aud:n.client_id,sub:r.user_id,iss:t.var.custom_domain?`https://${t.var.custom_domain}`:t.env.ISSUER,sid:s,nonce:n.nonce,given_name:r.given_name,family_name:r.family_name,nickname:r.nickname,picture:r.picture,locale:r.locale,name:r.name,email:r.email,email_verified:r.email_verified}:void 0;(w=t.env.hooks)!=null&&w.onExecuteCredentialsExchange&&await t.env.hooks.onExecuteCredentialsExchange({client:i,user:r,request:{ip:t.req.header("x-real-ip")||"",user_agent:t.req.header("user-agent")||"",method:t.req.method,url:t.req.url},scope:n.scope||"",grant_type:""},{accessToken:{setCustomClaim:(S,N)=>{if(Ju.includes(S))throw new Error(`Cannot overwrite reserved claim '${S}'`);p[S]=N}},idToken:{setCustomClaim:(S,N)=>{if(Ju.includes(S))throw new Error(`Cannot overwrite reserved claim '${S}'`);f&&(f[S]=N)}},access:{deny:S=>{throw new z(400,{message:`Access denied: ${S}`})}}});const m={includeIssuedTimestamp:!0,expiresIn:new sl(1,"d"),headers:{kid:l.kid}},v=await Du("RS256",u,p,m),h=f?await Du("RS256",u,f,m):void 0;return{access_token:v,refresh_token:e.refresh_token,id_token:h,token_type:"Bearer",expires_in:86400}}async function Hf(t,e){return e.loginSession||(e.loginSession=await t.env.data.loginSessions.create(e.client.tenant.id,{expires_at:new Date(Date.now()+Jn*1e3).toISOString(),authParams:e.authParams,authorization_url:t.req.url,csrf_token:xe(),...on(t.req)})),{code:(await t.env.data.codes.create(e.client.tenant.id,{code_id:xe(),user_id:e.user.user_id,code_type:"authorization_code",login_id:e.loginSession.id,expires_at:new Date(Date.now()+C_*1e3).toISOString()})).code_id,state:e.authParams.state}}async function oy(t,e){const{client:n,scope:r,audience:i=n.tenant.audience,session_id:s}=e;return await t.env.data.refreshTokens.create(n.tenant.id,{id:xe(),session_id:s,client_id:n.id,expires_at:new Date(Date.now()+Qs*1e3).toISOString(),user_id:e.user.user_id,device:{last_ip:t.req.header("x-real-ip")||"",initial_ip:t.req.header("x-real-ip")||"",last_user_agent:t.req.header("user-agent")||"",initial_user_agent:t.req.header("user-agent")||"",initial_asn:"",last_asn:""},resource_servers:[{audience:i,scopes:r}],rotating:!1})}async function Ff(t,{user:e,client:n,loginSession:r}){const i=await t.env.data.sessions.create(n.tenant.id,{id:xe(),user_id:e.user_id,idle_expires_at:new Date(Date.now()+Qs*1e3).toISOString(),device:{last_ip:t.req.header("x-real-ip")||"",initial_ip:t.req.header("x-real-ip")||"",last_user_agent:t.req.header("user-agent")||"",initial_user_agent:t.req.header("user-agent")||"",initial_asn:"",last_asn:""},clients:[n.id]});await t.env.data.loginSessions.update(n.tenant.id,r.id,{session_id:i.id});const{scope:s,audience:a}=r.authParams,c=s!=null&&s.split(" ").includes("offline_access")?await oy(t,{session_id:i.id,user:e,client:n,scope:s,audience:a}):void 0;return{...i,refresh_token:c}}async function an(t,e){var v;const{authParams:n,user:r,client:i,ticketAuth:s}=e,a=ve(t,{type:he.SUCCESS_LOGIN,description:`Successful login for ${r.user_id}`,userId:r.user_id});if(nt(t,t.env.data.logs.create(i.tenant.id,a)),nt(t,t.env.data.users.update(i.tenant.id,r.user_id,{last_login:new Date().toISOString(),last_ip:t.req.header("x-real-ip")||"",login_count:r.login_count+1})),s){if(!e.loginSession)throw new z(500,{message:"Login session not found"});const h=S_(),_=xe(12),w=await t.env.data.codes.create(i.tenant.id,{code_id:xe(),code_type:"ticket",login_id:e.loginSession.id,expires_at:new Date(Date.now()+j_).toISOString(),code_verifier:[_,h].join("|")});return t.json({login_ticket:w.code_id,co_verifier:h,co_id:_})}let c=e.refreshToken,l=e.sessionId,u=r;if(!l){if(!e.loginSession)throw new z(500,{message:"Login session not found"});u=await uy(t,t.env.data)(i.tenant.id,r);const h=await Ff(t,{user:r,client:i,loginSession:e.loginSession});l=h.id,c=(v=h.refresh_token)==null?void 0:v.id}if(e.authParams.response_mode===Xt.SAML_POST)return ty(t,e.client,e.authParams,u,l);const p=await to(t,{authParams:n,user:u,client:i,session_id:l,refresh_token:c}),f=new Headers({"set-cookie":Pf(i.tenant.id,l,t.req.header("host"))});if(n.response_mode===Xt.WEB_MESSAGE)return t.json(p,{headers:f});if((n.response_type||Pt.CODE)===Pt.CODE){const h=await Hf(t,e);if(!n.redirect_uri)throw new z(400,{message:"Redirect uri not found"});const _=new URL(n.redirect_uri);_.searchParams.set("code",h.code),h.state&&_.searchParams.set("state",h.state),f.set("location",_.toString())}return new Response("Redirecting",{status:302,headers:f})}async function ay(t,e,n){const r=await t.env.data.tenants.get(e);if(!r)throw new Error(`Tenant not found: ${e}`);return to(t,{client:{id:t.env.ISSUER,tenant:r,created_at:new Date().toISOString(),updated_at:new Date().toISOString(),name:t.env.ISSUER,disable_sign_ups:!1,connections:[]},authParams:{client_id:t.env.ISSUER,response_type:Pt.TOKEN,scope:n}})}async function dl(t,e,n){const r=await ay(t,n.tenant_id,"webhook");for await(const i of e)if(!(await fetch(i.url,{method:"POST",headers:{Authorization:`Bearer ${r.access_token}`,"Content-Type":"application/json"},body:JSON.stringify(n)})).ok){const a=ve(t,{type:he.FAILED_HOOK,description:`Failed to invoke hook ${i.hook_id}`});await t.env.data.logs.create(n.tenant_id,a)}}function cy(t){return async(e,n)=>{const{hooks:r}=await t.env.data.hooks.list(e);return await dl(t,r,{tenant_id:e,user:n,trigger_id:"post-user-registration"}),n}}function ly(t){return async(e,n)=>{const{hooks:r}=await t.env.data.hooks.list(e,{q:"trigger_id:pre-user-signup",page:0,per_page:100,include_totals:!1});await dl(t,r,{tenant_id:e,email:n,trigger_id:"pre-user-signup"})}}function uy(t,e){return async(n,r)=>{const{hooks:i}=await e.hooks.list(n,{q:"trigger_id:post-user-login",page:0,per_page:100,include_totals:!1});return await dl(t,i,{tenant_id:n,user:r,trigger_id:"post-user-login"}),r}}function dy(t,e){return async(n,r)=>{var a,c,l;const i={method:t.req.method,ip:t.req.query("x-real-ip")||"",user_agent:t.req.query("user-agent"),url:((a=t.var.loginSession)==null?void 0:a.authorization_url)||t.req.url};if((c=t.env.hooks)!=null&&c.onExecutePreUserRegistration)try{await t.env.hooks.onExecutePreUserRegistration({user:r,request:i},{user:{setUserMetadata:async(u,p)=>{r[u]=p}}})}catch{const p=ve(t,{type:he.FAILED_SIGNUP,description:"Pre user registration hook failed"});await e.logs.create(n,p)}let s=await __(e)(n,r);if((l=t.env.hooks)!=null&&l.onExecutePostUserRegistration)try{await t.env.hooks.onExecutePostUserRegistration({user:r,request:i},{user:{}})}catch{const p=ve(t,{type:he.FAILED_SIGNUP,description:"Post user registration hook failed"});await t.env.data.logs.create(n,p)}return await cy(t)(n,s),s}}async function py(t,e,n,r){var i,s;if(e.disable_sign_ups&&!(((s=(i=t.var.loginSession)==null?void 0:i.authParams)==null?void 0:s.prompt)==="signup")&&!await ro({userAdapter:n.users,tenant_id:e.tenant.id,email:r})){const l=ve(t,{type:he.FAILED_SIGNUP,description:"Public signup is disabled"});throw await n.logs.create(e.tenant.id,l),new z(400,{message:"Signups are disabled for this client"})}await ly(t)(t.var.tenant_id||"",r)}function no(t,e){return{...e,users:{...e.users,create:dy(t,e)}}}function Kf(t){return no(t,t.env.data)}async function pl(t,e,n){return(await t.list(e,{page:0,per_page:10,include_totals:!1,q:`email:${n}`})).users}async function ur({userAdapter:t,tenant_id:e,email:n,provider:r}){const{users:i}=await t.list(e,{page:0,per_page:10,include_totals:!1,q:`email:${n} provider:${r}`});return i.length>1&&console.error("More than one user found for same email and provider"),i[0]||null}async function ro({userAdapter:t,tenant_id:e,email:n}){var c;const{users:r}=await t.list(e,{page:0,per_page:10,include_totals:!1,q:`email:${n}`}),i=r.filter(l=>!(l.provider==="auth2"&&!l.email_verified));if(i.length===0)return;const s=i.filter(l=>!l.linked_to);if(s.length>0)return s.length>1&&console.error("More than one primary user found for same email"),s[0];const a=await t.get(e,(c=i[0])==null?void 0:c.linked_to);if(!a)throw new Error("Primary account not found");return a}async function ls({userAdapter:t,tenant_id:e,email:n,provider:r}){const i=await ur({userAdapter:t,tenant_id:e,email:n,provider:r});return i?i.linked_to?t.get(e,i.linked_to):i:null}async function io(t,e){const{email:n,provider:r,connection:i,client:s,userId:a,isSocial:c,profileData:l={},ip:u=""}=e;let p=await ls({userAdapter:t.env.data.users,tenant_id:e.client.tenant.id,email:n,provider:r});if(!p){const f={user_id:`${r}|${a||Xs()}`,email:n,name:n,provider:r,connection:i,email_verified:!0,last_ip:u,is_social:c,last_login:new Date().toISOString(),profileData:JSON.stringify(l)};p=await Kf(t).users.create(s.tenant.id,f),t.set("user_id",p.user_id)}return p}const Qt=o.z.object({page:o.z.string().min(0).optional().default("0").transform(t=>parseInt(t,10)).openapi({description:"The page number where 0 is the first page"}),per_page:o.z.string().min(1).optional().default("10").transform(t=>parseInt(t,10)).openapi({description:"The number of items per page"}),include_totals:o.z.string().optional().default("false").transform(t=>t==="true").openapi({description:"If the total number of items should be included in the response"}),sort:o.z.string().regex(/^.+:(-1|1)$/).optional().openapi({description:"A property that should have the format 'string:-1' or 'string:1'"}),q:o.z.string().optional().openapi({description:"A lucene query string used to filter the results"})});function dr(t){if(!t)return;const[e,n]=t.split(":"),r=n==="1"?"asc":"desc";if(!(!e||!r))return{sort_by:e,sort_order:r}}const Zu=rn.extend({users:o.z.array(xt)}),fy=rn.extend({sessions:o.z.array(Ys)}),hy=new o.OpenAPIHono().openapi(o.createRoute({tags:["users"],method:"get",path:"/",request:{query:Qt,headers:o.z.object({"tenant-id":o.z.string()})},security:[{Bearer:["auth:read"]}],responses:{200:{content:{"application/json":{schema:o.z.union([o.z.array(xt),Zu])}},description:"List of users"}}}),async t=>{const{page:e,per_page:n,include_totals:r,sort:i,q:s}=t.req.valid("query"),{"tenant-id":a}=t.req.valid("header");if(s!=null&&s.includes("identities.profileData.email")){const p=s.split("=")[1],m=(await t.env.data.users.list(a,{page:e,per_page:n,include_totals:r,q:`email:${p}`})).users.filter(_=>_.linked_to),[v]=m;if(!v)return t.json([]);const h=await t.env.data.users.get(a,v.linked_to);if(!h)throw new z(500,{message:"Primary account not found"});return t.json([xt.parse(h)])}const c=["-_exists_:linked_to"];s&&c.push(s);const l=await t.env.data.users.list(a,{page:e,per_page:n,include_totals:r,sort:dr(i),q:c.join(" ")}),u=l.users.filter(p=>!p.linked_to);return r?t.json(Zu.parse({users:u,length:l.length,start:l.start,limit:l.limit})):t.json(o.z.array(xt).parse(u))}).openapi(o.createRoute({tags:["users"],method:"get",path:"/{user_id}",request:{headers:o.z.object({"tenant-id":o.z.string()}),params:o.z.object({user_id:o.z.string()})},security:[{Bearer:["auth:read"]}],responses:{200:{content:{"application/json":{schema:xt}},description:"List of users"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{"tenant-id":n}=t.req.valid("header"),r=await t.env.data.users.get(n,e);if(!r)throw new z(404);if(r.linked_to)throw new z(404,{message:"User is linked to another user"});return t.json(r)}).openapi(o.createRoute({tags:["users"],method:"delete",path:"/{user_id}",request:{headers:o.z.object({"tenant-id":o.z.string()}),params:o.z.object({user_id:o.z.string()})},security:[{Bearer:["auth:write"]}],responses:{200:{description:"Status"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{"tenant-id":n}=t.req.valid("header");if(!await t.env.data.users.remove(n,e))throw new z(404);return t.text("OK")}).openapi(o.createRoute({tags:["users"],method:"post",path:"/",request:{headers:o.z.object({"tenant-id":o.z.string()}),body:{content:{"application/json":{schema:o.z.object({...ts.shape})}}}},security:[{Bearer:["auth:write"]}],responses:{200:{content:{"application/json":{schema:xt}},description:"Status"}}}),async t=>{const{"tenant-id":e}=t.req.valid("header"),n=t.req.valid("json");t.set("body",n);const{email:r}=n;if(!r)throw new z(400,{message:"Email is required"});const i=r.toLowerCase(),s=`${n.provider}|${n.user_id||Xs()}`;try{const a=await t.env.data.users.create(e,{email:i,user_id:s,name:n.name||i,provider:n.provider,connection:n.connection,email_verified:n.email_verified||!1,last_ip:"",is_social:!1,last_login:new Date().toISOString()});t.set("user_id",a.user_id);const c=ve(t,{type:he.SUCCESS_API_OPERATION,description:"User created"});nt(t,t.env.data.logs.create(e,c));const l={...a,identities:[{connection:a.connection,provider:a.provider,user_id:qu(a.user_id),isSocial:a.is_social}]};return t.json(xt.parse(l),{status:201})}catch(a){throw a.message==="User already exists"?new z(409,{message:"User already exists"}):a}}).openapi(o.createRoute({tags:["users"],method:"patch",path:"/{user_id}",request:{headers:o.z.object({"tenant-id":o.z.string()}),body:{content:{"application/json":{schema:o.z.object({...ts.shape,verify_email:o.z.boolean(),password:o.z.string()}).partial()}}},params:o.z.object({user_id:o.z.string()})},security:[{Bearer:["auth:write"]}],responses:{200:{description:"Status"}}}),async t=>{var p;const{data:e}=t.env,{"tenant-id":n}=t.req.valid("header"),r=t.req.valid("json"),{user_id:i}=t.req.valid("param"),{verify_email:s,password:a,...c}=r,l=await e.users.get(n,i);if(!l)throw new z(404);if(c.email&&c.email!==l.email){const f=await pl(t.env.data.users,n,c.email);if(f.length&&f.some(m=>m.user_id!==i))throw new z(409,{message:"Another user with the same email address already exists."})}if(l.linked_to)throw new z(404,{message:"User is linked to another user"});if(await t.env.data.users.update(n,i,c),a){const f=(p=l.identities)==null?void 0:p.find(h=>h.connection==="Username-Password-Authentication");if(!f)throw new z(400,{message:"User does not have a password identity"});const m={user_id:f.user_id,password:await si.hash(a,10),algorithm:"bcrypt"};await e.passwords.get(n,f.user_id)?await e.passwords.update(n,m):await e.passwords.create(n,m)}const u=await t.env.data.users.get(n,i);if(!u)throw new z(500);return t.json(u)}).openapi(o.createRoute({tags:["users"],method:"post",path:"/{user_id}/identities",request:{headers:o.z.object({"tenant-id":o.z.string()}),body:{content:{"application/json":{schema:o.z.union([o.z.object({link_with:o.z.string()}),o.z.object({user_id:o.z.string(),provider:o.z.string(),connection:o.z.string().optional()})])}}},params:o.z.object({user_id:o.z.string()})},security:[{Bearer:["auth:write"]}],responses:{200:{content:{"application/json":{schema:o.z.array(o.z.object({connection:o.z.string(),provider:o.z.string(),user_id:o.z.string(),isSocial:o.z.boolean()}))}},description:"Status"}}}),async t=>{const{"tenant-id":e}=t.req.valid("header"),n=t.req.valid("json"),{user_id:r}=t.req.valid("param"),i="link_with"in n?n.link_with:n.user_id,s=await t.env.data.users.get(e,r);if(!s)throw new z(400,{message:"Linking an inexistent identity is not allowed."});await t.env.data.users.update(e,i,{linked_to:r});const a=await t.env.data.users.list(e,{page:0,per_page:10,include_totals:!1,q:`linked_to:${r}`}),c=[s,...a.users].map(l=>({connection:l.connection,provider:l.provider,user_id:qu(l.user_id),isSocial:l.is_social}));return t.json(c,{status:201})}).openapi(o.createRoute({tags:["users"],method:"delete",path:"/{user_id}/identities/{provider}/{linked_user_id}",request:{headers:o.z.object({"tenant-id":o.z.string()}),params:o.z.object({user_id:o.z.string(),provider:o.z.string(),linked_user_id:o.z.string()})},security:[{Bearer:["auth:write"]}],responses:{200:{content:{"application/json":{schema:o.z.array(xt)}},description:"Status"}}}),async t=>{const{"tenant-id":e}=t.req.valid("header"),{user_id:n,provider:r,linked_user_id:i}=t.req.valid("param");await t.env.data.users.unlink(e,n,r,i);const s=await t.env.data.users.get(e,n);if(!s)throw new z(404);return t.json([xt.parse(s)])}).openapi(o.createRoute({tags:["users"],method:"get",path:"/{user_id}/sessions",request:{query:Qt,headers:o.z.object({"tenant-id":o.z.string()}),params:o.z.object({user_id:o.z.string()})},security:[{Bearer:["auth:read"]}],responses:{200:{content:{"application/json":{schema:o.z.union([o.z.array(Ys),fy])}},description:"List of sessions"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{include_totals:n}=t.req.valid("query"),{"tenant-id":r}=t.req.valid("header"),i=await t.env.data.sessions.list(r,{page:0,per_page:10,include_totals:!1,q:`user_id:${e}`});return n?t.json(i):t.json(i.sessions)});/*! *****************************************************************************
|
|
29
|
+
</html>`;return new Response(i,{headers:{"Content-Type":"text/html"}})}async function ty(t,e,n,r,i){var m,v,h;if(!n.redirect_uri)throw new z(400,{message:"Missing redirect_uri in authParams"});const[s]=await t.env.data.keys.list();if(!s)throw new z(500,{message:"No signing key found"});if(!((m=e.addons)!=null&&m.samlp))throw new z(400,{message:`SAML Addon is not enabled for client ${e.id}`});const{recipient:a,audience:c}=e.addons.samlp,l=n.state||"";if(!a||!l||!r||!n.state)throw new z(400,{message:"Missing recipient or inResponseTo"});const u=JSON.parse(n.state),p=new URL(n.redirect_uri),f=await ny(t,{issuer:t.env.ISSUER,audience:c||n.client_id,destination:p.toString(),inResponseTo:u.requestId,userId:((h=(v=r.app_metadata)==null?void 0:v.vimeo)==null?void 0:h.user_id)||r.user_id,email:r.email,sessionIndex:i,signature:{privateKeyPem:s.pkcs7,cert:s.cert,kid:s.kid}});return ey(p.toString(),f,u.relayState)}async function ny(t,e){const n=e.notBefore||new Date().toISOString(),r=e.notAfter||new Date(new Date(n).getTime()+10*60*1e3).toISOString(),i=e.issueInstant||n,s=e.sessionNotOnOrAfter||r,a=e.responseId||`_${xe()}`,c=e.assertionId||`_${xe()}`,l=[{"samlp:Response":[{"saml:Issuer":[{"#text":e.issuer}]},{"samlp:Status":[{"samlp:StatusCode":[],":@":{"@_Value":"urn:oasis:names:tc:SAML:2.0:status:Success"}}]},{"saml:Assertion":[{"saml:Issuer":[{"#text":e.issuer}]},{"saml:Subject":[{"saml:NameID":[{"#text":e.email}],":@":{"@_Format":"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"}},{"saml:SubjectConfirmation":[{"saml:SubjectConfirmationData":[],":@":{"@_InResponseTo":e.inResponseTo,"@_NotOnOrAfter":r,"@_Recipient":e.destination}}],":@":{"@_Method":"urn:oasis:names:tc:SAML:2.0:cm:bearer"}}]},{"saml:Conditions":[{"saml:AudienceRestriction":[{"saml:Audience":[{"#text":e.audience}]}]}],":@":{"@_NotBefore":n,"@_NotOnOrAfter":r}},{"saml:AuthnStatement":[{"saml:AuthnContext":[{"saml:AuthnContextClassRef":[{"#text":"urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified"}]}]}],":@":{"@_AuthnInstant":i,"@_SessionIndex":e.sessionIndex,"@_SessionNotOnOrAfter":s}},{"saml:AttributeStatement":[{"saml:Attribute":[{"saml:AttributeValue":[{"#text":e.userId}],":@":{"@_xmlns:xs":"http://www.w3.org/2001/XMLSchema","@_xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance","@_xsi:type":"xs:string"}}],":@":{"@_FriendlyName":"persistent","@_Name":"id","@_NameFormat":"urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"}},{"saml:Attribute":[{"saml:AttributeValue":[{"#text":e.email}],":@":{"@_xmlns:xs":"http://www.w3.org/2001/XMLSchema","@_xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance","@_xsi:type":"xs:string"}}],":@":{"@_Name":"email","@_NameFormat":"urn:oasis:names:tc:SAML:2.0:attrname-format:basic"}},{"saml:Attribute":[{"saml:AttributeValue":[{"#text":"manage-account"}],":@":{"@_xmlns:xs":"http://www.w3.org/2001/XMLSchema","@_xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance","@_xsi:type":"xs:string"}}],":@":{"@_Name":"Role","@_NameFormat":"urn:oasis:names:tc:SAML:2.0:attrname-format:basic"}},{"saml:Attribute":[{"saml:AttributeValue":[{"#text":"default-roles-master"}],":@":{"@_xmlns:xs":"http://www.w3.org/2001/XMLSchema","@_xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance","@_xsi:type":"xs:string"}}],":@":{"@_Name":"Role","@_NameFormat":"urn:oasis:names:tc:SAML:2.0:attrname-format:basic"}},{"saml:Attribute":[{"saml:AttributeValue":[{"#text":"offline_access"}],":@":{"@_xmlns:xs":"http://www.w3.org/2001/XMLSchema","@_xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance","@_xsi:type":"xs:string"}}],":@":{"@_Name":"Role","@_NameFormat":"urn:oasis:names:tc:SAML:2.0:attrname-format:basic"}},{"saml:Attribute":[{"saml:AttributeValue":[{"#text":"view-profile"}],":@":{"@_xmlns:xs":"http://www.w3.org/2001/XMLSchema","@_xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance","@_xsi:type":"xs:string"}}],":@":{"@_Name":"Role","@_NameFormat":"urn:oasis:names:tc:SAML:2.0:attrname-format:basic"}},{"saml:Attribute":[{"saml:AttributeValue":[{"#text":"uma_authorization"}],":@":{"@_xmlns:xs":"http://www.w3.org/2001/XMLSchema","@_xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance","@_xsi:type":"xs:string"}}],":@":{"@_Name":"Role","@_NameFormat":"urn:oasis:names:tc:SAML:2.0:attrname-format:basic"}},{"saml:Attribute":[{"saml:AttributeValue":[{"#text":"manage-account-links"}],":@":{"@_xmlns:xs":"http://www.w3.org/2001/XMLSchema","@_xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance","@_xsi:type":"xs:string"}}],":@":{"@_Name":"Role","@_NameFormat":"urn:oasis:names:tc:SAML:2.0:attrname-format:basic"}}]}],":@":{"@_xmlns":"urn:oasis:names:tc:SAML:2.0:assertion","@_ID":c,"@_IssueInstant":i,"@_Version":"2.0"}}],":@":{"@_xmlns:samlp":"urn:oasis:names:tc:SAML:2.0:protocol","@_xmlns:saml":"urn:oasis:names:tc:SAML:2.0:assertion","@_Destination":e.destination,"@_ID":a,"@_InResponseTo":e.inResponseTo,"@_IssueInstant":i,"@_Version":"2.0"}}];let p=new Q0.XMLBuilder({ignoreAttributes:!1,suppressEmptyNode:!0,preserveOrder:!0}).build(l);if(e.signature){const m=await fetch(t.env.SAML_SIGN_URL,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({xmlContent:p,privateKey:e.signature.privateKeyPem,publicCert:e.signature.cert})});if(!m.ok)throw new Error(`Failed to sign SAML response: ${m.status}`);p=await m.text()}return e.encode===!1?p:btoa(p)}var ry={deno:"Deno",bun:"Bun",workerd:"Cloudflare-Workers",node:"Node.js"},iy=()=>{var n,r;const t=globalThis;if(typeof navigator<"u"&&typeof navigator.userAgent=="string"){for(const[i,s]of Object.entries(ry))if(sy(s))return i}return typeof(t==null?void 0:t.EdgeRuntime)=="string"?"edge-light":(t==null?void 0:t.fastly)!==void 0?"fastly":((r=(n=t==null?void 0:t.process)==null?void 0:n.release)==null?void 0:r.name)==="node"?"node":"other"},sy=t=>navigator.userAgent.startsWith(t);function nt(t,e){iy()==="workerd"&&t.executionCtx.waitUntil(e)}function on(t){var e,n,r;return{auth0Client:(e=t.query("auth0Client"))==null?void 0:e.slice(0,255),ip:(n=t.header("x-real-ip"))==null?void 0:n.slice(0,45),useragent:(r=t.header("user-agent"))==null?void 0:r.slice(0,512)}}const Ju=["sub","iss","aud","exp","nbf","iat","jti"];async function to(t,e){var _,w;const{authParams:n,user:r,client:i,session_id:s}=e,c=(await t.env.data.keys.list()).filter(S=>!S.revoked_at||new Date(S.revoked_at)>new Date),l=c[c.length-1];if(!(l!=null&&l.pkcs7))throw new z(500,{message:"No signing key available"});const u=A_(l.pkcs7),p={aud:n.audience||"default",scope:n.scope||"",sub:(r==null?void 0:r.user_id)||n.client_id,iss:t.var.custom_domain?`https://${t.var.custom_domain}/`:t.env.ISSUER,tenant_id:t.var.tenant_id,sid:s},f=r&&((_=n.scope)!=null&&_.split(" ").includes("openid"))?{aud:n.client_id,sub:r.user_id,iss:t.var.custom_domain?`https://${t.var.custom_domain}`:t.env.ISSUER,sid:s,nonce:n.nonce,given_name:r.given_name,family_name:r.family_name,nickname:r.nickname,picture:r.picture,locale:r.locale,name:r.name,email:r.email,email_verified:r.email_verified}:void 0;(w=t.env.hooks)!=null&&w.onExecuteCredentialsExchange&&await t.env.hooks.onExecuteCredentialsExchange({client:i,user:r,request:{ip:t.req.header("x-real-ip")||"",user_agent:t.req.header("user-agent")||"",method:t.req.method,url:t.req.url},scope:n.scope||"",grant_type:""},{accessToken:{setCustomClaim:(S,N)=>{if(Ju.includes(S))throw new Error(`Cannot overwrite reserved claim '${S}'`);p[S]=N}},idToken:{setCustomClaim:(S,N)=>{if(Ju.includes(S))throw new Error(`Cannot overwrite reserved claim '${S}'`);f&&(f[S]=N)}},access:{deny:S=>{throw new z(400,{message:`Access denied: ${S}`})}}});const m={includeIssuedTimestamp:!0,expiresIn:new sl(1,"d"),headers:{kid:l.kid}},v=await Du("RS256",u,p,m),h=f?await Du("RS256",u,f,m):void 0;return{access_token:v,refresh_token:e.refresh_token,id_token:h,token_type:"Bearer",expires_in:86400}}async function Hf(t,e){return e.loginSession||(e.loginSession=await t.env.data.loginSessions.create(e.client.tenant.id,{expires_at:new Date(Date.now()+Jn*1e3).toISOString(),authParams:e.authParams,authorization_url:t.req.url,csrf_token:xe(),...on(t.req)})),{code:(await t.env.data.codes.create(e.client.tenant.id,{code_id:xe(),user_id:e.user.user_id,code_type:"authorization_code",login_id:e.loginSession.id,expires_at:new Date(Date.now()+C_*1e3).toISOString()})).code_id,state:e.authParams.state}}async function oy(t,e){const{client:n,scope:r,audience:i=n.tenant.audience,session_id:s}=e;return await t.env.data.refreshTokens.create(n.tenant.id,{id:xe(),session_id:s,client_id:n.id,expires_at:new Date(Date.now()+Qs*1e3).toISOString(),user_id:e.user.user_id,device:{last_ip:t.req.header("x-real-ip")||"",initial_ip:t.req.header("x-real-ip")||"",last_user_agent:t.req.header("user-agent")||"",initial_user_agent:t.req.header("user-agent")||"",initial_asn:"",last_asn:""},resource_servers:[{audience:i,scopes:r}],rotating:!1})}async function Ff(t,{user:e,client:n,loginSession:r}){const i=await t.env.data.sessions.create(n.tenant.id,{id:xe(),user_id:e.user_id,idle_expires_at:new Date(Date.now()+Qs*1e3).toISOString(),device:{last_ip:t.req.header("x-real-ip")||"",initial_ip:t.req.header("x-real-ip")||"",last_user_agent:t.req.header("user-agent")||"",initial_user_agent:t.req.header("user-agent")||"",initial_asn:"",last_asn:""},clients:[n.id]});await t.env.data.loginSessions.update(n.tenant.id,r.id,{session_id:i.id});const{scope:s,audience:a}=r.authParams,c=s!=null&&s.split(" ").includes("offline_access")?await oy(t,{session_id:i.id,user:e,client:n,scope:s,audience:a}):void 0;return{...i,refresh_token:c}}async function an(t,e){var v;const{authParams:n,user:r,client:i,ticketAuth:s}=e,a=ve(t,{type:he.SUCCESS_LOGIN,description:`Successful login for ${r.user_id}`,userId:r.user_id});if(nt(t,t.env.data.logs.create(i.tenant.id,a)),nt(t,t.env.data.users.update(i.tenant.id,r.user_id,{last_login:new Date().toISOString(),last_ip:t.req.header("x-real-ip")||"",login_count:r.login_count+1})),s){if(!e.loginSession)throw new z(500,{message:"Login session not found"});const h=S_(),_=xe(12),w=await t.env.data.codes.create(i.tenant.id,{code_id:xe(),code_type:"ticket",login_id:e.loginSession.id,expires_at:new Date(Date.now()+j_).toISOString(),code_verifier:[_,h].join("|")});return t.json({login_ticket:w.code_id,co_verifier:h,co_id:_})}let c=e.refreshToken,l=e.sessionId,u=r;if(!l){if(!e.loginSession)throw new z(500,{message:"Login session not found"});u=await uy(t,t.env.data)(i.tenant.id,r);const h=await Ff(t,{user:r,client:i,loginSession:e.loginSession});l=h.id,c=(v=h.refresh_token)==null?void 0:v.id}if(e.authParams.response_mode===Xt.SAML_POST)return ty(t,e.client,e.authParams,u,l);const p=await to(t,{authParams:n,user:u,client:i,session_id:l,refresh_token:c}),f=new Headers({"set-cookie":Pf(i.tenant.id,l,t.req.header("host"))});if(n.response_mode===Xt.WEB_MESSAGE)return t.json(p,{headers:f});if((n.response_type||Pt.CODE)===Pt.CODE){const h=await Hf(t,e);if(!n.redirect_uri)throw new z(400,{message:"Redirect uri not found"});const _=new URL(n.redirect_uri);_.searchParams.set("code",h.code),h.state&&_.searchParams.set("state",h.state),f.set("location",_.toString())}return new Response("Redirecting",{status:302,headers:f})}async function ay(t,e,n){const r=await t.env.data.tenants.get(e);if(!r)throw new Error(`Tenant not found: ${e}`);return to(t,{client:{id:t.env.ISSUER,tenant:r,created_at:new Date().toISOString(),updated_at:new Date().toISOString(),name:t.env.ISSUER,disable_sign_ups:!1,connections:[]},authParams:{client_id:t.env.ISSUER,response_type:Pt.TOKEN,scope:n}})}async function dl(t,e,n){const r=await ay(t,n.tenant_id,"webhook");for await(const i of e)if(!(await fetch(i.url,{method:"POST",headers:{Authorization:`Bearer ${r.access_token}`,"Content-Type":"application/json"},body:JSON.stringify(n)})).ok){const a=ve(t,{type:he.FAILED_HOOK,description:`Failed to invoke hook ${i.hook_id}`});await t.env.data.logs.create(n.tenant_id,a)}}function cy(t){return async(e,n)=>{const{hooks:r}=await t.env.data.hooks.list(e);return await dl(t,r,{tenant_id:e,user:n,trigger_id:"post-user-registration"}),n}}function ly(t){return async(e,n)=>{const{hooks:r}=await t.env.data.hooks.list(e,{q:"trigger_id:pre-user-signup",page:0,per_page:100,include_totals:!1});await dl(t,r,{tenant_id:e,email:n,trigger_id:"pre-user-signup"})}}function uy(t,e){return async(n,r)=>{const{hooks:i}=await e.hooks.list(n,{q:"trigger_id:post-user-login",page:0,per_page:100,include_totals:!1});return await dl(t,i,{tenant_id:n,user:r,trigger_id:"post-user-login"}),r}}function dy(t,e){return async(n,r)=>{var a,c,l;const i={method:t.req.method,ip:t.req.query("x-real-ip")||"",user_agent:t.req.query("user-agent"),url:((a=t.var.loginSession)==null?void 0:a.authorization_url)||t.req.url};if((c=t.env.hooks)!=null&&c.onExecutePreUserRegistration)try{await t.env.hooks.onExecutePreUserRegistration({user:r,request:i},{user:{setUserMetadata:async(u,p)=>{r[u]=p}}})}catch{const p=ve(t,{type:he.FAILED_SIGNUP,description:"Pre user registration hook failed"});await e.logs.create(n,p)}let s=await __(e)(n,r);if((l=t.env.hooks)!=null&&l.onExecutePostUserRegistration)try{await t.env.hooks.onExecutePostUserRegistration({user:r,request:i},{user:{}})}catch{const p=ve(t,{type:he.FAILED_SIGNUP,description:"Post user registration hook failed"});await t.env.data.logs.create(n,p)}return await cy(t)(n,s),s}}async function py(t,e,n,r){var i,s;if(e.disable_sign_ups&&!(((s=(i=t.var.loginSession)==null?void 0:i.authParams)==null?void 0:s.prompt)==="signup")&&!await ro({userAdapter:n.users,tenant_id:e.tenant.id,email:r})){const l=ve(t,{type:he.FAILED_SIGNUP,description:"Public signup is disabled"});throw await n.logs.create(e.tenant.id,l),new z(400,{message:"Signups are disabled for this client"})}await ly(t)(t.var.tenant_id||"",r)}function no(t,e){return{...e,users:{...e.users,create:dy(t,e)}}}function Kf(t){return no(t,t.env.data)}async function pl(t,e,n){return(await t.list(e,{page:0,per_page:10,include_totals:!1,q:`email:${n}`})).users}async function ur({userAdapter:t,tenant_id:e,email:n,provider:r}){const{users:i}=await t.list(e,{page:0,per_page:10,include_totals:!1,q:`email:${n} provider:${r}`});return i.length>1&&console.error("More than one user found for same email and provider"),i[0]||null}async function ro({userAdapter:t,tenant_id:e,email:n}){var c;const{users:r}=await t.list(e,{page:0,per_page:10,include_totals:!1,q:`email:${n}`}),i=r.filter(l=>!(l.provider==="auth2"&&!l.email_verified));if(i.length===0)return;const s=i.filter(l=>!l.linked_to);if(s.length>0)return s.length>1&&console.error("More than one primary user found for same email"),s[0];const a=await t.get(e,(c=i[0])==null?void 0:c.linked_to);if(!a)throw new Error("Primary account not found");return a}async function ls({userAdapter:t,tenant_id:e,email:n,provider:r}){const i=await ur({userAdapter:t,tenant_id:e,email:n,provider:r});return i?i.linked_to?t.get(e,i.linked_to):i:null}async function io(t,e){const{email:n,provider:r,connection:i,client:s,userId:a,isSocial:c,profileData:l={},ip:u=""}=e;let p=await ls({userAdapter:t.env.data.users,tenant_id:e.client.tenant.id,email:n,provider:r});if(!p){const f={user_id:`${r}|${a||Xs()}`,email:n,name:n,provider:r,connection:i,email_verified:!0,last_ip:u,is_social:c,last_login:new Date().toISOString(),profileData:JSON.stringify(l)};p=await Kf(t).users.create(s.tenant.id,f),t.set("user_id",p.user_id)}return p}const Qt=o.z.object({page:o.z.string().min(0).optional().default("0").transform(t=>parseInt(t,10)).openapi({description:"The page number where 0 is the first page"}),per_page:o.z.string().min(1).optional().default("10").transform(t=>parseInt(t,10)).openapi({description:"The number of items per page"}),include_totals:o.z.string().optional().default("false").transform(t=>t==="true").openapi({description:"If the total number of items should be included in the response"}),sort:o.z.string().regex(/^.+:(-1|1)$/).optional().openapi({description:"A property that should have the format 'string:-1' or 'string:1'"}),q:o.z.string().optional().openapi({description:"A lucene query string used to filter the results"})});function dr(t){if(!t)return;const[e,n]=t.split(":"),r=n==="1"?"asc":"desc";if(!(!e||!r))return{sort_by:e,sort_order:r}}const Zu=rn.extend({users:o.z.array(xt)}),fy=rn.extend({sessions:o.z.array(Ys)}),hy=new o.OpenAPIHono().openapi(o.createRoute({tags:["users"],method:"get",path:"/",request:{query:Qt,headers:o.z.object({"tenant-id":o.z.string()})},security:[{Bearer:["auth:read"]}],responses:{200:{content:{"application/json":{schema:o.z.union([o.z.array(xt),Zu])}},description:"List of users"}}}),async t=>{const{page:e,per_page:n,include_totals:r,sort:i,q:s}=t.req.valid("query"),{"tenant-id":a}=t.req.valid("header");if(s!=null&&s.includes("identities.profileData.email")){const p=s.split("=")[1],m=(await t.env.data.users.list(a,{page:e,per_page:n,include_totals:r,q:`email:${p}`})).users.filter(_=>_.linked_to),[v]=m;if(!v)return t.json([]);const h=await t.env.data.users.get(a,v.linked_to);if(!h)throw new z(500,{message:"Primary account not found"});return t.json([xt.parse(h)])}const c=["-_exists_:linked_to"];s&&c.push(s);const l=await t.env.data.users.list(a,{page:e,per_page:n,include_totals:r,sort:dr(i),q:c.join(" ")}),u=l.users.filter(p=>!p.linked_to);return r?t.json(Zu.parse({users:u,length:l.length,start:l.start,limit:l.limit})):t.json(o.z.array(xt).parse(u))}).openapi(o.createRoute({tags:["users"],method:"get",path:"/{user_id}",request:{headers:o.z.object({"tenant-id":o.z.string()}),params:o.z.object({user_id:o.z.string()})},security:[{Bearer:["auth:read"]}],responses:{200:{content:{"application/json":{schema:xt}},description:"List of users"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{"tenant-id":n}=t.req.valid("header"),r=await t.env.data.users.get(n,e);if(!r)throw new z(404);if(r.linked_to)throw new z(404,{message:"User is linked to another user"});return t.json(r)}).openapi(o.createRoute({tags:["users"],method:"delete",path:"/{user_id}",request:{headers:o.z.object({"tenant-id":o.z.string()}),params:o.z.object({user_id:o.z.string()})},security:[{Bearer:["auth:write"]}],responses:{200:{description:"Status"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{"tenant-id":n}=t.req.valid("header");if(!await t.env.data.users.remove(n,e))throw new z(404);return t.text("OK")}).openapi(o.createRoute({tags:["users"],method:"post",path:"/",request:{headers:o.z.object({"tenant-id":o.z.string()}),body:{content:{"application/json":{schema:o.z.object({...ts.shape})}}}},security:[{Bearer:["auth:write"]}],responses:{200:{content:{"application/json":{schema:xt}},description:"Status"}}}),async t=>{const{"tenant-id":e}=t.req.valid("header"),n=t.req.valid("json");t.set("body",n);const{email:r}=n;if(!r)throw new z(400,{message:"Email is required"});const i=r.toLowerCase(),s=`${n.provider}|${n.user_id||Xs()}`;try{const a=await t.env.data.users.create(e,{email:i,user_id:s,name:n.name||i,provider:n.provider,connection:n.connection,email_verified:n.email_verified||!1,last_ip:"",is_social:!1,last_login:new Date().toISOString()});t.set("user_id",a.user_id);const c=ve(t,{type:he.SUCCESS_API_OPERATION,description:"User created"});nt(t,t.env.data.logs.create(e,c));const l={...a,identities:[{connection:a.connection,provider:a.provider,user_id:qu(a.user_id),isSocial:a.is_social}]};return t.json(xt.parse(l),{status:201})}catch(a){throw a.message==="User already exists"?new z(409,{message:"User already exists"}):a}}).openapi(o.createRoute({tags:["users"],method:"patch",path:"/{user_id}",request:{headers:o.z.object({"tenant-id":o.z.string()}),body:{content:{"application/json":{schema:o.z.object({...ts.shape,verify_email:o.z.boolean(),password:o.z.string()}).partial()}}},params:o.z.object({user_id:o.z.string()})},security:[{Bearer:["auth:write"]}],responses:{200:{description:"Status"}}}),async t=>{var p;const{data:e}=t.env,{"tenant-id":n}=t.req.valid("header"),r=t.req.valid("json"),{user_id:i}=t.req.valid("param"),{verify_email:s,password:a,...c}=r,l=await e.users.get(n,i);if(!l)throw new z(404);if(c.email&&c.email!==l.email){const f=await pl(t.env.data.users,n,c.email);if(f.length&&f.some(m=>m.user_id!==i))throw new z(409,{message:"Another user with the same email address already exists."})}if(l.linked_to)throw new z(404,{message:"User is linked to another user"});if(await t.env.data.users.update(n,i,c),a){const f=(p=l.identities)==null?void 0:p.find(h=>h.connection==="Username-Password-Authentication");if(!f)throw new z(400,{message:"User does not have a password identity"});const m={user_id:f.user_id,password:await si.hash(a,10),algorithm:"bcrypt"};await e.passwords.get(n,f.user_id)?await e.passwords.update(n,m):await e.passwords.create(n,m)}const u=await t.env.data.users.get(n,i);if(!u)throw new z(500);return t.json(u)}).openapi(o.createRoute({tags:["users"],method:"post",path:"/{user_id}/identities",request:{headers:o.z.object({"tenant-id":o.z.string()}),body:{content:{"application/json":{schema:o.z.union([o.z.object({link_with:o.z.string()}),o.z.object({user_id:o.z.string(),provider:o.z.string(),connection:o.z.string().optional()})])}}},params:o.z.object({user_id:o.z.string()})},security:[{Bearer:["auth:write"]}],responses:{200:{content:{"application/json":{schema:o.z.array(o.z.object({connection:o.z.string(),provider:o.z.string(),user_id:o.z.string(),isSocial:o.z.boolean()}))}},description:"Status"}}}),async t=>{const{"tenant-id":e}=t.req.valid("header"),n=t.req.valid("json"),{user_id:r}=t.req.valid("param"),i="link_with"in n?n.link_with:n.user_id,s=await t.env.data.users.get(e,r);if(!s)throw new z(400,{message:"Linking an inexistent identity is not allowed."});await t.env.data.users.update(e,i,{linked_to:r});const a=await t.env.data.users.list(e,{page:0,per_page:10,include_totals:!1,q:`linked_to:${r}`}),c=[s,...a.users].map(l=>({connection:l.connection,provider:l.provider,user_id:qu(l.user_id),isSocial:l.is_social}));return t.json(c,{status:201})}).openapi(o.createRoute({tags:["users"],method:"delete",path:"/{user_id}/identities/{provider}/{linked_user_id}",request:{headers:o.z.object({"tenant-id":o.z.string()}),params:o.z.object({user_id:o.z.string(),provider:o.z.string(),linked_user_id:o.z.string()})},security:[{Bearer:["auth:write"]}],responses:{200:{content:{"application/json":{schema:o.z.array(xt)}},description:"Status"}}}),async t=>{const{"tenant-id":e}=t.req.valid("header"),{user_id:n,provider:r,linked_user_id:i}=t.req.valid("param");await t.env.data.users.unlink(e,n,r,i);const s=await t.env.data.users.get(e,n);if(!s)throw new z(404);return t.json([xt.parse(s)])}).openapi(o.createRoute({tags:["users"],method:"get",path:"/{user_id}/sessions",request:{query:Qt,headers:o.z.object({"tenant-id":o.z.string()}),params:o.z.object({user_id:o.z.string()})},security:[{Bearer:["auth:read"]}],responses:{200:{content:{"application/json":{schema:o.z.union([o.z.array(Ys),fy])}},description:"List of sessions"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{include_totals:n}=t.req.valid("query"),{"tenant-id":r}=t.req.valid("header"),i=await t.env.data.sessions.list(r,{page:0,per_page:10,include_totals:!1,q:`user_id:${e}`});return n?t.json(i):t.json(i.sessions)});/*! *****************************************************************************
|
|
30
30
|
Copyright (C) Microsoft. All rights reserved.
|
|
31
31
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
32
32
|
this file except in compliance with the License. You may obtain a copy of the
|
package/dist/authhero.mjs
CHANGED
|
@@ -5549,7 +5549,7 @@ async function Ks(t, e) {
|
|
|
5549
5549
|
aud: n.audience || "default",
|
|
5550
5550
|
scope: n.scope || "",
|
|
5551
5551
|
sub: (r == null ? void 0 : r.user_id) || n.client_id,
|
|
5552
|
-
iss: t.var.custom_domain ? `https://${t.var.custom_domain}
|
|
5552
|
+
iss: t.var.custom_domain ? `https://${t.var.custom_domain}/` : t.env.ISSUER,
|
|
5553
5553
|
tenant_id: t.var.tenant_id,
|
|
5554
5554
|
sid: s
|
|
5555
5555
|
}, f = r && ((_ = n.scope) != null && _.split(" ").includes("openid")) ? {
|