authhero 0.209.0 → 0.210.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
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
<\/script>
|
|
70
70
|
</body>
|
|
71
71
|
|
|
72
|
-
</html>`}const Eh=["sub","iss","aud","exp","nbf","iat","jti"];async function Oc(t,e){var T,O;const{authParams:n,user:r,client:i,session_id:o}=e,{signingKeys:a}=await t.env.data.keys.list({q:"type:jwt_signing"}),l=a.filter(x=>!x.revoked_at||new Date(x.revoked_at)>new Date),u=l[l.length-1];if(!(u!=null&&u.pkcs7))throw new E(500,{message:"No signing key available"});const d=qv(u.pkcs7),p=t.var.custom_domain?`https://${t.var.custom_domain}/`:t.env.ISSUER,h={aud:n.audience||"default",scope:n.scope||"",sub:(r==null?void 0:r.user_id)||n.client_id,iss:p,tenant_id:t.var.tenant_id,sid:o},g=r&&((T=n.scope)!=null&&T.split(" ").includes("openid"))?{aud:n.client_id,sub:r.user_id,iss:p,sid:o,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;(O=t.env.hooks)!=null&&O.onExecuteCredentialsExchange&&await t.env.hooks.onExecuteCredentialsExchange({ctx:t,client:i,user:r,request:{ip:t.var.ip||"",user_agent:t.var.useragent||"",method:t.req.method,url:t.req.url},scope:n.scope||"",grant_type:""},{accessToken:{setCustomClaim:(x,M)=>{if(Eh.includes(x))throw new Error(`Cannot overwrite reserved claim '${x}'`);h[x]=M}},idToken:{setCustomClaim:(x,M)=>{if(Eh.includes(x))throw new Error(`Cannot overwrite reserved claim '${x}'`);g&&(g[x]=M)}},access:{deny:x=>{throw new E(400,{message:`Access denied: ${x}`})}}});const $={includeIssuedTimestamp:!0,expiresIn:new $p(1,"d"),headers:{kid:u.kid}},A=await wh("RS256",d,h,$),z=g?await wh("RS256",d,g,$):void 0;return{access_token:A,refresh_token:e.refresh_token,id_token:z,token_type:"Bearer",expires_in:86400}}async function q_(t,e){return{code:(await t.env.data.codes.create(e.client.tenant.id,{code_id:Me(),user_id:e.user.user_id,code_type:"authorization_code",login_id:e.login_id,expires_at:new Date(Date.now()+Kv*1e3).toISOString(),code_challenge:e.authParams.code_challenge,code_challenge_method:e.authParams.code_challenge_method,redirect_uri:e.authParams.redirect_uri,state:e.authParams.state,nonce:e.authParams.nonce})).code_id,state:e.authParams.state}}async function V_(t,e){const{client:n,scope:r,audience:i=n.tenant.audience,session_id:o}=e;return await t.env.data.refreshTokens.create(n.tenant.id,{id:Me(),session_id:o,client_id:n.id,idle_expires_at:new Date(Date.now()+Ic*1e3).toISOString(),user_id:e.user.user_id,device:{last_ip:t.var.ip,initial_ip:t.var.ip,last_user_agent:t.var.useragent||"",initial_user_agent:t.var.useragent||"",initial_asn:"",last_asn:""},resource_servers:[{audience:i,scopes:r}],rotating:!1})}async function H_(t,{user:e,client:n,loginSession:r}){const i=await t.env.data.sessions.create(n.tenant.id,{id:Me(),user_id:e.user_id,login_session_id:r.id,idle_expires_at:new Date(Date.now()+Ic*1e3).toISOString(),device:{last_ip:t.var.ip||"",initial_ip:t.var.ip||"",last_user_agent:t.var.useragent||"",initial_user_agent:t.var.useragent||"",initial_asn:"",last_asn:""},clients:[n.id]});return await t.env.data.loginSessions.update(n.tenant.id,r.id,{session_id:i.id}),i}async function Dn(t,e){var A,z;const{authParams:n,client:r,ticketAuth:i}=e;let{user:o}=e;const a=n.response_type||Zt.CODE,l=n.response_mode||zn.QUERY,u=qe(t,{type:Fe.SUCCESS_LOGIN,description:`Successful login for ${o.user_id}`,userId:o.user_id});if(ln(t,t.env.data.logs.create(r.tenant.id,u)),ln(t,t.env.data.users.update(r.tenant.id,o.user_id,{last_login:new Date().toISOString(),last_ip:t.var.ip||"",login_count:o.login_count+1})),i){if(!e.loginSession)throw new E(500,{message:"Login session not found for ticket auth."});const T=Mv(),O=Me(12),x=await t.env.data.codes.create(r.tenant.id,{code_id:Me(),code_type:"ticket",login_id:e.loginSession.id,expires_at:new Date(Date.now()+Wv).toISOString(),code_verifier:[O,T].join("|"),redirect_uri:n.redirect_uri,state:n.state,nonce:n.nonce});return t.json({login_ticket:x.code_id,co_verifier:T,co_id:O})}let d=e.refreshToken,p=e.sessionId;if(!p&&((A=e.loginSession)!=null&&A.session_id)){p=e.loginSession.session_id;const T=await t.env.data.sessions.get(r.tenant.id,p);T&&!T.clients.includes(r.id)&&await t.env.data.sessions.update(r.tenant.id,p,{clients:[...T.clients,r.id]})}else if(!p){if(!e.loginSession)throw new E(500,{message:"Login session not found for creating a new session."});p=(await H_(t,{user:o,client:r,loginSession:e.loginSession})).id}if(!d&&((z=n.scope)!=null&&z.split(" ").includes("offline_access"))&&![Zt.TOKEN,Zt.CODE].includes(a)&&(d=(await V_(t,{user:o,client:r,session_id:p,scope:n.scope,audience:n.audience})).id),l===zn.SAML_POST){if(!p)throw new E(500,{message:"Session ID not available for SAML response"});return _3(t,e.client,e.authParams,o,p)}const h=await b3(t,{authParams:n,user:o,client:r,session_id:p,refresh_token:d,strategy:e.strategy,loginSession:e.loginSession,responseType:a,skipHooks:e.skipHooks});if(h instanceof Response)return h;if(l===zn.WEB_MESSAGE){if(!n.redirect_uri)throw new E(400,{message:"Redirect URI not allowed for WEB_MESSAGE response mode."});const T=new Headers;if(p){const M=Ta(r.tenant.id,p,t.var.host||"");M&&T.set("set-cookie",M)}else console.warn("Session ID not available for WEB_MESSAGE, cookie will not be set.");const O=new URL(n.redirect_uri),x=`${O.protocol}//${O.host}`;return t.html(Iu(x,JSON.stringify({...h,state:n.state})),{headers:T})}if(!n.redirect_uri)throw new E(400,{message:"Redirect uri not found for this response mode."});const g=new Headers;if(p){const T=Ta(r.tenant.id,p,t.var.custom_domain||t.req.header("host")||"");T&&g.set("set-cookie",T)}const $=new URL(n.redirect_uri);if("code"in h)$.searchParams.set("code",h.code),h.state&&$.searchParams.set("state",h.state);else if("access_token"in h)$.hash=new URLSearchParams({access_token:h.access_token,...h.id_token&&{id_token:h.id_token},token_type:h.token_type,expires_in:h.expires_in.toString(),...n.state&&{state:n.state},...n.scope&&{scope:n.scope}}).toString();else throw new E(500,{message:"Invalid token response for implicit flow."});return g.set("location",$.toString()),new Response("Redirecting",{status:302,headers:g})}async function b3(t,e){var i;let{user:n}=e;const r=e.responseType||Zt.TOKEN;if(e.loginSession&&n&&!e.skipHooks){((i=n.app_metadata)==null?void 0:i.strategy)!==e.strategy&&(n.app_metadata={...n.app_metadata,strategy:e.strategy},await t.env.data.users.update(e.client.tenant.id,n.user_id,{app_metadata:{...n.app_metadata||{},strategy:e.strategy}}));const o=await z3(t,t.env.data,e.client.tenant.id,n,e.loginSession,{client:e.client,authParams:e.authParams});if(o instanceof Response)return o;n=o}if(r===Zt.CODE){if(!n||!e.loginSession)throw new E(500,{message:"User and loginSession is required for code flow"});return await q_(t,{user:n,client:e.client,authParams:e.authParams,login_id:e.loginSession.id})}else return Oc(t,{...e,user:n})}async function $3(t,e,n){const r=await t.env.data.tenants.get(e);if(!r)throw new Error(`Tenant not found: ${e}`);return Oc(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:Zt.TOKEN,scope:n}})}async function K_(t,e,n){const r=await $3(t,n.tenant_id,"webhook");for await(const i of e.filter(o=>"url"in o))if(!(await fetch(i.url,{method:"POST",headers:{Authorization:`Bearer ${r.access_token}`,"Content-Type":"application/json"},body:JSON.stringify(n)})).ok){const a=qe(t,{type:Fe.FAILED_HOOK,description:`Failed to invoke hook ${i.hook_id}`});await t.env.data.logs.create(n.tenant_id,a)}}function x3(t){return async(e,n)=>{const{hooks:r}=await t.env.data.hooks.list(e);return await K_(t,r,{tenant_id:e,user:n,trigger_id:"post-user-registration"}),n}}function A3(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 K_(t,r,{tenant_id:e,email:n,trigger_id:"pre-user-signup"})}}function Sh(t){return typeof t.form_id=="string"}async function E3(t,e,n){var u;const r=t.env.data,i=t.var.tenant_id||t.req.header("tenant-id");if(!i)throw new E(400,{message:"Missing tenant_id in context"});const o=await r.forms.get(i,e);if(!o)throw new E(404,{message:"Form not found for post-user-login hook"});let a=(u=o.start)==null?void 0:u.next_node;if(!a&&o.nodes&&o.nodes.length>0){const d=o.nodes.find(p=>p.type==="STEP");a=d==null?void 0:d.id}if(!a)throw new E(400,{message:"No start node found in form"});let l=`/u/forms/${o.id}/nodes/${a}?state=${encodeURIComponent(n.id)}`;return new Response(null,{status:302,headers:{location:l}})}function kh(t){return typeof t.page_id=="string"&&typeof t.enabled=="boolean"}async function S3(t,e,n,r,i){const o=t.env.data,a=t.var.tenant_id||t.req.header("tenant-id");if(!a)throw new E(400,{message:"Missing tenant_id in context"});if(i&&!(await o.userPermissions.list(a,r.user_id)).some(p=>p.permission_name===i))return r;let l=`/u/${e}?state=${encodeURIComponent(n.id)}`;return new Response(null,{status:302,headers:{location:l}})}function Nh(t){return typeof t.url=="string"}function k3(t,e){return async(n,r)=>{var a,l,u;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((l=t.env.hooks)!=null&&l.onExecutePreUserRegistration)try{await t.env.hooks.onExecutePreUserRegistration({ctx:t,user:r,request:i},{user:{setUserMetadata:async(d,p)=>{r[d]=p}}})}catch{const p=qe(t,{type:Fe.FAILED_SIGNUP,description:"Pre user registration hook failed"});await e.logs.create(n,p)}let o=await jv(e)(n,r);if((u=t.env.hooks)!=null&&u.onExecutePostUserRegistration)try{await t.env.hooks.onExecutePostUserRegistration({ctx:t,user:r,request:i},{user:{}})}catch{const p=qe(t,{type:Fe.FAILED_SIGNUP,description:"Post user registration hook failed"});await t.env.data.logs.create(n,p)}return await x3(t)(n,o),o}}function N3(t,e){return async(n,r,i)=>{var a,l;const o={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((l=t.env.hooks)!=null&&l.onExecutePreUserUpdate)try{await t.env.hooks.onExecutePreUserUpdate({ctx:t,user_id:r,updates:i,request:o},{user:{setUserMetadata:async(u,d)=>{i[u]=d}},cancel:()=>{throw new E(400,{message:"User update cancelled by pre-update hook"})}})}catch(u){if(u instanceof E)throw u;const d=qe(t,{type:Fe.FAILED_HOOK,description:"Pre user update hook failed"});throw await e.logs.create(n,d),new E(400,{message:"Pre user update hook failed"})}if(await e.users.update(n,r,i),i.email){const u=qe(t,{type:Fe.SUCCESS_CHANGE_EMAIL,description:`Email updated to ${i.email}`,userId:r});await e.logs.create(n,u),console.log("log:",u)}return!0}}async function C3(t,e,n,r){var i;if(e.disable_sign_ups){const o=(i=t.var.loginSession)==null?void 0:i.authorization_url;if(!(o&&new URL(o).searchParams.get("screen_hint")==="signup")&&!await zp({userAdapter:n.users,tenant_id:e.tenant.id,email:r})){const u=qe(t,{type:Fe.FAILED_SIGNUP,description:"Public signup is disabled"});throw await n.logs.create(e.tenant.id,u),new E(400,{message:"Signups are disabled for this client"})}}await A3(t)(t.var.tenant_id||"",r)}function os(t,e){return{...e,users:{...e.users,create:k3(t,e),update:N3(t,e)}}}async function z3(t,e,n,r,i,o){var u;(u=t.env.hooks)!=null&&u.onExecutePostLogin&&(o!=null&&o.client)&&(o!=null&&o.authParams)&&await t.env.hooks.onExecutePostLogin({ctx:t,client:o.client,user:r,request:{ip:t.var.ip,user_agent:t.var.useragent,method:t.req.method,url:t.req.url},scope:o.authParams.scope||"",grant_type:""},{prompt:{render:d=>{}}});const{hooks:a}=await e.hooks.list(n,{q:"trigger_id:post-user-login",page:0,per_page:100,include_totals:!1});if(i){const d=a.find(h=>h.enabled&&Sh(h));if(d&&Sh(d))return E3(t,d.form_id,i);const p=a.find(h=>h.enabled&&kh(h));if(p&&kh(p))return S3(t,p.page_id,i,r,p.permission_required)}const l=a.filter(d=>d.enabled&&Nh(d));for(const d of l)if(Nh(d))try{await fetch(d.url,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({tenant_id:n,user:r,trigger_id:"post-user-login"})})}catch{const h=qe(t,{type:Fe.FAILED_HOOK,description:`Failed to invoke post-user-login webhook: ${d.url}`});await e.logs.create(n,h)}return r}function I3(t){return os(t,t.env.data)}async function Cp(t,e,n){return(await t.list(e,{page:0,per_page:10,include_totals:!1,q:`email:${n}`})).users}async function Yi({userAdapter:t,tenant_id:e,username:n,provider:r}){const i=r==="sms"?`phone_number:${n}`:`email:${n}`,{users:o}=await t.list(e,{page:0,per_page:10,include_totals:!1,q:`${i} provider:${r}`});return o.length>1&&console.error("More than one user found for same email and provider"),o[0]||null}async function zp({userAdapter:t,tenant_id:e,email:n}){var l;const{users:r}=await t.list(e,{page:0,per_page:10,include_totals:!1,q:`email:${n}`}),i=r.filter(u=>!(u.provider==="auth2"&&!u.email_verified));if(i.length===0)return;const o=i.filter(u=>!u.linked_to);if(o.length>0)return o.length>1&&console.error("More than one primary user found for same email"),o[0];const a=await t.get(e,(l=i[0])==null?void 0:l.linked_to);if(!a)throw new Error("Primary account not found");return a}async function Ro({userAdapter:t,tenant_id:e,username:n,provider:r}){const i=await Yi({userAdapter:t,tenant_id:e,username:n,provider:r});return i?i.linked_to?t.get(e,i.linked_to):i:null}async function Dc(t,e){const{username:n,provider:r,connection:i,client:o,userId:a,isSocial:l,profileData:u={},ip:d=""}=e;let p=await Ro({userAdapter:t.env.data.users,tenant_id:e.client.tenant.id,username:n,provider:r});if(!p){const h={user_id:`${r}|${a||zc()}`,email:i!=="sms"?n:void 0,phone_number:i==="sms"?n:void 0,name:n,provider:r,connection:i,email_verified:!0,last_ip:d,is_social:l,last_login:new Date().toISOString(),profileData:JSON.stringify(u)};p=await I3(t).users.create(o.tenant.id,h),t.set("user_id",p.user_id)}return p}const ot=s.z.object({page:s.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:s.z.string().min(1).optional().default("10").transform(t=>parseInt(t,10)).openapi({description:"The number of items per page"}),include_totals:s.z.string().optional().default("false").transform(t=>t==="true").openapi({description:"If the total number of items should be included in the response"}),sort:s.z.string().regex(/^.+:(-1|1)$/).optional().openapi({description:"A property that should have the format 'string:-1' or 'string:1'"}),q:s.z.string().optional().openapi({description:"A lucene query string used to filter the results"})});function vt(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 Ch=Ut.extend({users:s.z.array(kn)}),T3=Ut.extend({sessions:s.z.array(Nc)}),O3=Ut.extend({organizations:s.z.array(hr)}),D3=new s.OpenAPIHono().openapi(s.createRoute({tags:["users"],method:"get",path:"/",request:{query:ot,headers:s.z.object({"tenant-id":s.z.string()})},security:[{Bearer:["auth:read"]}],responses:{200:{content:{"application/json":{schema:s.z.union([s.z.array(kn),Ch])}},description:"List of users"}}}),async t=>{const{page:e,per_page:n,include_totals:r,sort:i,q:o}=t.req.valid("query"),{"tenant-id":a}=t.req.valid("header");if(o!=null&&o.includes("identities.profileData.email")){const p=o.split("=")[1],g=(await t.env.data.users.list(a,{page:e,per_page:n,include_totals:r,q:`email:${p}`})).users.filter(z=>z.linked_to),[$]=g;if(!$)return t.json([]);const A=await t.env.data.users.get(a,$.linked_to);if(!A)throw new E(500,{message:"Primary account not found"});return t.json([kn.parse(A)])}const l=["-_exists_:linked_to"];o&&l.push(o);const u=await t.env.data.users.list(a,{page:e,per_page:n,include_totals:r,sort:vt(i),q:l.join(" ")}),d=u.users.filter(p=>!p.linked_to);return r?t.json(Ch.parse({users:d,length:u.length,start:u.start,limit:u.limit})):t.json(s.z.array(kn).parse(d))}).openapi(s.createRoute({tags:["users"],method:"get",path:"/{user_id}",request:{headers:s.z.object({"tenant-id":s.z.string()}),params:s.z.object({user_id:s.z.string()})},security:[{Bearer:["auth:read"]}],responses:{200:{content:{"application/json":{schema:kn}},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 E(404);if(r.linked_to)throw new E(404,{message:"User is linked to another user"});return t.json(r)}).openapi(s.createRoute({tags:["users"],method:"delete",path:"/{user_id}",request:{headers:s.z.object({"tenant-id":s.z.string()}),params:s.z.object({user_id:s.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 E(404);return t.text("OK")}).openapi(s.createRoute({tags:["users"],method:"post",path:"/",request:{headers:s.z.object({"tenant-id":s.z.string()}),body:{content:{"application/json":{schema:s.z.object({...$a.shape})}}}},security:[{Bearer:["auth:write"]}],responses:{201:{content:{"application/json":{schema:kn}},description:"Status"}}}),async t=>{const{"tenant-id":e}=t.req.valid("header"),n=t.req.valid("json");t.set("body",n);const{email:r,phone_number:i,name:o,linked_to:a,email_verified:l,provider:u,connection:d}=n,p=`${n.provider}|${n.user_id||zc()}`;try{const h=await t.env.data.users.create(e,{email:r,user_id:p,name:o||r||i,phone_number:i,provider:u,connection:d,linked_to:a??void 0,email_verified:l||!1,last_ip:"",is_social:!1,last_login:new Date().toISOString()});t.set("user_id",h.user_id);const g=qe(t,{type:Fe.SUCCESS_API_OPERATION,description:"User created"});ln(t,t.env.data.logs.create(e,g));const $={...h,identities:[{connection:h.connection,provider:h.provider,user_id:_h(h.user_id),isSocial:h.is_social}]};return t.json(kn.parse($),{status:201})}catch(h){throw h.message==="User already exists"?new E(409,{message:"User already exists"}):h}}).openapi(s.createRoute({tags:["users"],method:"patch",path:"/{user_id}",request:{headers:s.z.object({"tenant-id":s.z.string()}),body:{content:{"application/json":{schema:s.z.object({...$a.shape,verify_email:s.z.boolean(),password:s.z.string()}).partial()}}},params:s.z.object({user_id:s.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:o,password:a,...l}=r,u=await e.users.get(n,i);if(!u)throw new E(404);if(l.email&&l.email!==u.email){const h=await Cp(t.env.data.users,n,l.email);if(h.length&&h.some(g=>g.user_id!==i))throw new E(409,{message:"Another user with the same email address already exists."})}if(u.linked_to)throw new E(404,{message:"User is linked to another user"});if(await t.env.data.users.update(n,i,l),a){const h=(p=u.identities)==null?void 0:p.find(A=>A.connection==="Username-Password-Authentication");if(!h)throw new E(400,{message:"User does not have a password identity"});const g={user_id:h.user_id,password:await is.hash(a,10),algorithm:"bcrypt"};await e.passwords.get(n,h.user_id)?await e.passwords.update(n,g):await e.passwords.create(n,g)}const d=await t.env.data.users.get(n,i);if(!d)throw new E(500);return t.json(d)}).openapi(s.createRoute({tags:["users"],method:"post",path:"/{user_id}/identities",request:{headers:s.z.object({"tenant-id":s.z.string()}),body:{content:{"application/json":{schema:s.z.union([s.z.object({link_with:s.z.string()}),s.z.object({user_id:s.z.string(),provider:s.z.string(),connection:s.z.string().optional()})])}}},params:s.z.object({user_id:s.z.string()})},security:[{Bearer:["auth:write"]}],responses:{201:{content:{"application/json":{schema:s.z.array(s.z.object({connection:s.z.string(),provider:s.z.string(),user_id:s.z.string(),isSocial:s.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,o=await t.env.data.users.get(e,r);if(!o)throw new E(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}`}),l=[o,...a.users].map(u=>({connection:u.connection,provider:u.provider,user_id:_h(u.user_id),isSocial:u.is_social}));return t.json(l,{status:201})}).openapi(s.createRoute({tags:["users"],method:"delete",path:"/{user_id}/identities/{provider}/{linked_user_id}",request:{headers:s.z.object({"tenant-id":s.z.string()}),params:s.z.object({user_id:s.z.string(),provider:s.z.string(),linked_user_id:s.z.string()})},security:[{Bearer:["auth:write"]}],responses:{200:{content:{"application/json":{schema:s.z.array(kn)}},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 o=await t.env.data.users.get(e,n);if(!o)throw new E(404);return t.json([kn.parse(o)])}).openapi(s.createRoute({tags:["users"],method:"get",path:"/{user_id}/sessions",request:{query:ot,headers:s.z.object({"tenant-id":s.z.string()}),params:s.z.object({user_id:s.z.string()})},security:[{Bearer:["auth:read"]}],responses:{200:{content:{"application/json":{schema:s.z.union([s.z.array(Nc),T3])}},description:"List of sessions"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{include_totals:n,page:r,per_page:i}=t.req.valid("query"),{"tenant-id":o}=t.req.valid("header"),a=await t.env.data.sessions.list(o,{page:r,per_page:i,include_totals:n,q:`user_id:${e}`});return n?t.json(a):t.json(a.sessions)}).openapi(s.createRoute({tags:["users"],method:"get",path:"/{user_id}/permissions",request:{params:s.z.object({user_id:s.z.string()}),headers:s.z.object({"tenant-id":s.z.string()}),query:ot},security:[{Bearer:["auth:read"]}],responses:{200:{content:{"application/json":{schema:v_}},description:"User permissions"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{"tenant-id":n}=t.req.valid("header"),{page:r,per_page:i,sort:o,q:a}=t.req.valid("query");if(!await t.env.data.users.get(n,e))throw new E(404,{message:"User not found"});const u=await t.env.data.userPermissions.list(n,e,{page:r,per_page:i,include_totals:!1,sort:vt(o),q:a});return t.json(u)}).openapi(s.createRoute({tags:["users"],method:"post",path:"/{user_id}/permissions",request:{params:s.z.object({user_id:s.z.string()}),headers:s.z.object({"tenant-id":s.z.string()}),body:{content:{"application/json":{schema:s.z.object({permissions:s.z.array(s.z.object({permission_name:s.z.string(),resource_server_identifier:s.z.string()}))})}}}},security:[{Bearer:["auth:write"]}],responses:{201:{description:"Permissions assigned to user"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{"tenant-id":n}=t.req.valid("header"),{permissions:r}=t.req.valid("json");if(!await t.env.data.users.get(n,e))throw new E(404,{message:"User not found"});for(const o of r)if(!await t.env.data.userPermissions.create(n,e,{user_id:e,resource_server_identifier:o.resource_server_identifier,permission_name:o.permission_name}))throw new E(500,{message:"Failed to assign permissions to user"});return t.json({message:"Permissions assigned successfully"},{status:201})}).openapi(s.createRoute({tags:["users"],method:"delete",path:"/{user_id}/permissions",request:{params:s.z.object({user_id:s.z.string()}),headers:s.z.object({"tenant-id":s.z.string()}),body:{content:{"application/json":{schema:s.z.object({permissions:s.z.array(s.z.object({permission_name:s.z.string(),resource_server_identifier:s.z.string()}))})}}}},security:[{Bearer:["auth:write"]}],responses:{200:{description:"Permissions removed from user"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{"tenant-id":n}=t.req.valid("header"),{permissions:r}=t.req.valid("json");if(!await t.env.data.users.get(n,e))throw new E(404,{message:"User not found"});for(const o of r)if(!await t.env.data.userPermissions.remove(n,e,o))throw new E(500,{message:"Failed to remove permissions from user"});return t.json({message:"Permissions removed successfully"})}).openapi(s.createRoute({tags:["users"],method:"get",path:"/{user_id}/roles",request:{params:s.z.object({user_id:s.z.string()}),headers:s.z.object({"tenant-id":s.z.string()})},security:[{Bearer:["auth:read"]}],responses:{200:{content:{"application/json":{schema:za}},description:"User roles"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{"tenant-id":n}=t.req.valid("header");if(!await t.env.data.users.get(n,e))throw new E(404,{message:"User not found"});const i=await t.env.data.userRoles.list(n,e,void 0,"");return t.json(i)}).openapi(s.createRoute({tags:["users"],method:"post",path:"/{user_id}/roles",request:{params:s.z.object({user_id:s.z.string()}),headers:s.z.object({"tenant-id":s.z.string()}),body:{content:{"application/json":{schema:s.z.object({roles:s.z.array(s.z.string())})}}}},security:[{Bearer:["auth:write"]}],responses:{201:{description:"Roles assigned to user"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{"tenant-id":n}=t.req.valid("header"),{roles:r}=t.req.valid("json");if(!await t.env.data.users.get(n,e))throw new E(404,{message:"User not found"});for(const o of r)if(!await t.env.data.userRoles.create(n,e,o,""))throw new E(500,{message:"Failed to assign roles to user"});return t.json({message:"Roles assigned successfully"},{status:201})}).openapi(s.createRoute({tags:["users"],method:"delete",path:"/{user_id}/roles",request:{params:s.z.object({user_id:s.z.string()}),headers:s.z.object({"tenant-id":s.z.string()}),body:{content:{"application/json":{schema:s.z.object({roles:s.z.array(s.z.string())})}}}},security:[{Bearer:["auth:write"]}],responses:{200:{description:"Roles removed from user"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{"tenant-id":n}=t.req.valid("header"),{roles:r}=t.req.valid("json");if(!await t.env.data.users.get(n,e))throw new E(404,{message:"User not found"});for(const o of r)if(!await t.env.data.userRoles.remove(n,e,o,""))throw new E(500,{message:"Failed to remove roles from user"});return t.json({message:"Roles removed successfully"})}).openapi(s.createRoute({tags:["users"],method:"get",path:"/{user_id}/organizations",request:{params:s.z.object({user_id:s.z.string()}),query:ot,headers:s.z.object({"tenant-id":s.z.string()})},security:[{Bearer:["auth:read"]}],responses:{200:{content:{"application/json":{schema:s.z.union([O3,s.z.array(hr)])}},description:"List of user organizations"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{"tenant-id":n}=t.req.valid("header"),{page:r,per_page:i,include_totals:o,sort:a}=t.req.valid("query");if(!await t.env.data.users.get(n,e))throw new E(404,{message:"User not found"});const u=await t.env.data.userOrganizations.listUserOrganizations(n,e,{page:r,per_page:i,sort:vt(a)});return o?t.json({organizations:u.organizations,start:u.start,limit:u.limit,length:u.length}):t.json(u.organizations)}).openapi(s.createRoute({tags:["users"],method:"delete",path:"/{user_id}/organizations/{organization_id}",request:{params:s.z.object({user_id:s.z.string(),organization_id:s.z.string()}),headers:s.z.object({"tenant-id":s.z.string()})},security:[{Bearer:["auth:write"]}],responses:{200:{description:"User removed from organization successfully"}}}),async t=>{const{user_id:e,organization_id:n}=t.req.valid("param"),{"tenant-id":r}=t.req.valid("header");if(!await t.env.data.users.get(r,e))throw new E(404,{message:"User not found"});const a=(await t.env.data.userOrganizations.list(r,{q:`user_id:${e}`,per_page:100})).userOrganizations.find(l=>l.organization_id===n);if(!a)throw new E(404,{message:"User is not a member of this organization"});return await t.env.data.userOrganizations.remove(r,a.id),t.json({message:"User removed from organization successfully"})});/*! *****************************************************************************
|
|
72
|
+
</html>`}const Eh=["sub","iss","aud","exp","nbf","iat","jti"];async function Oc(t,e){var T,O;const{authParams:n,user:r,client:i,session_id:o}=e,{signingKeys:a}=await t.env.data.keys.list({q:"type:jwt_signing"}),l=a.filter(x=>!x.revoked_at||new Date(x.revoked_at)>new Date),u=l[l.length-1];if(!(u!=null&&u.pkcs7))throw new E(500,{message:"No signing key available"});const d=qv(u.pkcs7),p=t.var.custom_domain?`https://${t.var.custom_domain}/`:t.env.ISSUER,h={aud:n.audience||"default",scope:n.scope||"",sub:(r==null?void 0:r.user_id)||n.client_id,iss:p,tenant_id:t.var.tenant_id,sid:o},g=r&&((T=n.scope)!=null&&T.split(" ").includes("openid"))?{aud:n.client_id,sub:r.user_id,iss:p,sid:o,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;(O=t.env.hooks)!=null&&O.onExecuteCredentialsExchange&&await t.env.hooks.onExecuteCredentialsExchange({ctx:t,client:i,user:r,request:{ip:t.var.ip||"",user_agent:t.var.useragent||"",method:t.req.method,url:t.req.url},scope:n.scope||"",grant_type:""},{accessToken:{setCustomClaim:(x,M)=>{if(Eh.includes(x))throw new Error(`Cannot overwrite reserved claim '${x}'`);h[x]=M}},idToken:{setCustomClaim:(x,M)=>{if(Eh.includes(x))throw new Error(`Cannot overwrite reserved claim '${x}'`);g&&(g[x]=M)}},access:{deny:x=>{throw new E(400,{message:`Access denied: ${x}`})}}});const $={includeIssuedTimestamp:!0,expiresIn:new $p(1,"d"),headers:{kid:u.kid}},A=await wh("RS256",d,h,$),z=g?await wh("RS256",d,g,$):void 0;return{access_token:A,refresh_token:e.refresh_token,id_token:z,token_type:"Bearer",expires_in:86400}}async function q_(t,e){return{code:(await t.env.data.codes.create(e.client.tenant.id,{code_id:Me(),user_id:e.user.user_id,code_type:"authorization_code",login_id:e.login_id,expires_at:new Date(Date.now()+Kv*1e3).toISOString(),code_challenge:e.authParams.code_challenge,code_challenge_method:e.authParams.code_challenge_method,redirect_uri:e.authParams.redirect_uri,state:e.authParams.state,nonce:e.authParams.nonce})).code_id,state:e.authParams.state}}async function V_(t,e){const{client:n,scope:r,audience:i=n.tenant.audience,session_id:o}=e;return await t.env.data.refreshTokens.create(n.tenant.id,{id:Me(),session_id:o,client_id:n.id,idle_expires_at:new Date(Date.now()+Ic*1e3).toISOString(),user_id:e.user.user_id,device:{last_ip:t.var.ip,initial_ip:t.var.ip,last_user_agent:t.var.useragent||"",initial_user_agent:t.var.useragent||"",initial_asn:"",last_asn:""},resource_servers:[{audience:i,scopes:r}],rotating:!1})}async function H_(t,{user:e,client:n,loginSession:r}){const i=await t.env.data.sessions.create(n.tenant.id,{id:Me(),user_id:e.user_id,login_session_id:r.id,idle_expires_at:new Date(Date.now()+Ic*1e3).toISOString(),device:{last_ip:t.var.ip||"",initial_ip:t.var.ip||"",last_user_agent:t.var.useragent||"",initial_user_agent:t.var.useragent||"",initial_asn:"",last_asn:""},clients:[n.id]});return await t.env.data.loginSessions.update(n.tenant.id,r.id,{session_id:i.id}),i}async function Dn(t,e){var A,z;const{authParams:n,client:r,ticketAuth:i}=e;let{user:o}=e;const a=n.response_type||Zt.CODE,l=n.response_mode||zn.QUERY,u=qe(t,{type:Fe.SUCCESS_LOGIN,description:`Successful login for ${o.user_id}`,userId:o.user_id});if(ln(t,t.env.data.logs.create(r.tenant.id,u)),ln(t,t.env.data.users.update(r.tenant.id,o.user_id,{last_login:new Date().toISOString(),last_ip:t.var.ip||"",login_count:o.login_count+1})),i){if(!e.loginSession)throw new E(500,{message:"Login session not found for ticket auth."});const T=Mv(),O=Me(12),x=await t.env.data.codes.create(r.tenant.id,{code_id:Me(),code_type:"ticket",login_id:e.loginSession.id,expires_at:new Date(Date.now()+Wv).toISOString(),code_verifier:[O,T].join("|"),redirect_uri:n.redirect_uri,state:n.state,nonce:n.nonce});return t.json({login_ticket:x.code_id,co_verifier:T,co_id:O})}let d=e.refreshToken,p=e.sessionId;if(!p&&((A=e.loginSession)!=null&&A.session_id)){p=e.loginSession.session_id;const T=await t.env.data.sessions.get(r.tenant.id,p);T&&!T.clients.includes(r.id)&&await t.env.data.sessions.update(r.tenant.id,p,{clients:[...T.clients,r.id]})}else if(!p){if(!e.loginSession)throw new E(500,{message:"Login session not found for creating a new session."});p=(await H_(t,{user:o,client:r,loginSession:e.loginSession})).id}if(!d&&((z=n.scope)!=null&&z.split(" ").includes("offline_access"))&&![Zt.TOKEN,Zt.CODE].includes(a)&&(d=(await V_(t,{user:o,client:r,session_id:p,scope:n.scope,audience:n.audience})).id),l===zn.SAML_POST){if(!p)throw new E(500,{message:"Session ID not available for SAML response"});return _3(t,e.client,e.authParams,o,p)}const h=await b3(t,{authParams:n,user:o,client:r,session_id:p,refresh_token:d,strategy:e.strategy,loginSession:e.loginSession,responseType:a,skipHooks:e.skipHooks});if(h instanceof Response)return h;if(l===zn.WEB_MESSAGE){if(!n.redirect_uri)throw new E(400,{message:"Redirect URI not allowed for WEB_MESSAGE response mode."});const T=new Headers;if(p){const M=Ta(r.tenant.id,p,t.var.host||"");M&&T.set("set-cookie",M)}else console.warn("Session ID not available for WEB_MESSAGE, cookie will not be set.");const O=new URL(n.redirect_uri),x=`${O.protocol}//${O.host}`;return t.html(Iu(x,JSON.stringify({...h,state:n.state})),{headers:T})}if(!n.redirect_uri)throw new E(400,{message:"Redirect uri not found for this response mode."});const g=new Headers;if(p){const T=Ta(r.tenant.id,p,t.var.custom_domain||t.req.header("host")||"");T&&g.set("set-cookie",T)}const $=new URL(n.redirect_uri);if("code"in h)$.searchParams.set("code",h.code),h.state&&$.searchParams.set("state",h.state);else if("access_token"in h)$.hash=new URLSearchParams({access_token:h.access_token,...h.id_token&&{id_token:h.id_token},token_type:h.token_type,expires_in:h.expires_in.toString(),...n.state&&{state:n.state},...n.scope&&{scope:n.scope}}).toString();else throw new E(500,{message:"Invalid token response for implicit flow."});return g.set("location",$.toString()),new Response("Redirecting",{status:302,headers:g})}async function b3(t,e){var i;let{user:n}=e;const r=e.responseType||Zt.TOKEN;if(e.loginSession&&n&&!e.skipHooks){e.strategy&&((i=n.app_metadata)==null?void 0:i.strategy)!==e.strategy&&(n.app_metadata={...n.app_metadata,strategy:e.strategy},await t.env.data.users.update(e.client.tenant.id,n.user_id,{app_metadata:{...n.app_metadata||{},strategy:e.strategy}}));const o=await z3(t,t.env.data,e.client.tenant.id,n,e.loginSession,{client:e.client,authParams:e.authParams});if(o instanceof Response)return o;n=o}if(r===Zt.CODE){if(!n||!e.loginSession)throw new E(500,{message:"User and loginSession is required for code flow"});return await q_(t,{user:n,client:e.client,authParams:e.authParams,login_id:e.loginSession.id})}else return Oc(t,{...e,user:n})}async function $3(t,e,n){const r=await t.env.data.tenants.get(e);if(!r)throw new Error(`Tenant not found: ${e}`);return Oc(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:Zt.TOKEN,scope:n}})}async function K_(t,e,n){const r=await $3(t,n.tenant_id,"webhook");for await(const i of e.filter(o=>"url"in o))if(!(await fetch(i.url,{method:"POST",headers:{Authorization:`Bearer ${r.access_token}`,"Content-Type":"application/json"},body:JSON.stringify(n)})).ok){const a=qe(t,{type:Fe.FAILED_HOOK,description:`Failed to invoke hook ${i.hook_id}`});await t.env.data.logs.create(n.tenant_id,a)}}function x3(t){return async(e,n)=>{const{hooks:r}=await t.env.data.hooks.list(e);return await K_(t,r,{tenant_id:e,user:n,trigger_id:"post-user-registration"}),n}}function A3(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 K_(t,r,{tenant_id:e,email:n,trigger_id:"pre-user-signup"})}}function Sh(t){return typeof t.form_id=="string"}async function E3(t,e,n){var u;const r=t.env.data,i=t.var.tenant_id||t.req.header("tenant-id");if(!i)throw new E(400,{message:"Missing tenant_id in context"});const o=await r.forms.get(i,e);if(!o)throw new E(404,{message:"Form not found for post-user-login hook"});let a=(u=o.start)==null?void 0:u.next_node;if(!a&&o.nodes&&o.nodes.length>0){const d=o.nodes.find(p=>p.type==="STEP");a=d==null?void 0:d.id}if(!a)throw new E(400,{message:"No start node found in form"});let l=`/u/forms/${o.id}/nodes/${a}?state=${encodeURIComponent(n.id)}`;return new Response(null,{status:302,headers:{location:l}})}function kh(t){return typeof t.page_id=="string"&&typeof t.enabled=="boolean"}async function S3(t,e,n,r,i){const o=t.env.data,a=t.var.tenant_id||t.req.header("tenant-id");if(!a)throw new E(400,{message:"Missing tenant_id in context"});if(i&&!(await o.userPermissions.list(a,r.user_id)).some(p=>p.permission_name===i))return r;let l=`/u/${e}?state=${encodeURIComponent(n.id)}`;return new Response(null,{status:302,headers:{location:l}})}function Nh(t){return typeof t.url=="string"}function k3(t,e){return async(n,r)=>{var a,l,u;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((l=t.env.hooks)!=null&&l.onExecutePreUserRegistration)try{await t.env.hooks.onExecutePreUserRegistration({ctx:t,user:r,request:i},{user:{setUserMetadata:async(d,p)=>{r[d]=p}}})}catch{const p=qe(t,{type:Fe.FAILED_SIGNUP,description:"Pre user registration hook failed"});await e.logs.create(n,p)}let o=await jv(e)(n,r);if((u=t.env.hooks)!=null&&u.onExecutePostUserRegistration)try{await t.env.hooks.onExecutePostUserRegistration({ctx:t,user:r,request:i},{user:{}})}catch{const p=qe(t,{type:Fe.FAILED_SIGNUP,description:"Post user registration hook failed"});await t.env.data.logs.create(n,p)}return await x3(t)(n,o),o}}function N3(t,e){return async(n,r,i)=>{var a,l;const o={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((l=t.env.hooks)!=null&&l.onExecutePreUserUpdate)try{await t.env.hooks.onExecutePreUserUpdate({ctx:t,user_id:r,updates:i,request:o},{user:{setUserMetadata:async(u,d)=>{i[u]=d}},cancel:()=>{throw new E(400,{message:"User update cancelled by pre-update hook"})}})}catch(u){if(u instanceof E)throw u;const d=qe(t,{type:Fe.FAILED_HOOK,description:"Pre user update hook failed"});throw await e.logs.create(n,d),new E(400,{message:"Pre user update hook failed"})}if(await e.users.update(n,r,i),i.email){const u=qe(t,{type:Fe.SUCCESS_CHANGE_EMAIL,description:`Email updated to ${i.email}`,userId:r});await e.logs.create(n,u),console.log("log:",u)}return!0}}async function C3(t,e,n,r){var i;if(e.disable_sign_ups){const o=(i=t.var.loginSession)==null?void 0:i.authorization_url;if(!(o&&new URL(o).searchParams.get("screen_hint")==="signup")&&!await zp({userAdapter:n.users,tenant_id:e.tenant.id,email:r})){const u=qe(t,{type:Fe.FAILED_SIGNUP,description:"Public signup is disabled"});throw await n.logs.create(e.tenant.id,u),new E(400,{message:"Signups are disabled for this client"})}}await A3(t)(t.var.tenant_id||"",r)}function os(t,e){return{...e,users:{...e.users,create:k3(t,e),update:N3(t,e)}}}async function z3(t,e,n,r,i,o){var u;(u=t.env.hooks)!=null&&u.onExecutePostLogin&&(o!=null&&o.client)&&(o!=null&&o.authParams)&&await t.env.hooks.onExecutePostLogin({ctx:t,client:o.client,user:r,request:{ip:t.var.ip,user_agent:t.var.useragent,method:t.req.method,url:t.req.url},scope:o.authParams.scope||"",grant_type:""},{prompt:{render:d=>{}}});const{hooks:a}=await e.hooks.list(n,{q:"trigger_id:post-user-login",page:0,per_page:100,include_totals:!1});if(i){const d=a.find(h=>h.enabled&&Sh(h));if(d&&Sh(d))return E3(t,d.form_id,i);const p=a.find(h=>h.enabled&&kh(h));if(p&&kh(p))return S3(t,p.page_id,i,r,p.permission_required)}const l=a.filter(d=>d.enabled&&Nh(d));for(const d of l)if(Nh(d))try{await fetch(d.url,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({tenant_id:n,user:r,trigger_id:"post-user-login"})})}catch{const h=qe(t,{type:Fe.FAILED_HOOK,description:`Failed to invoke post-user-login webhook: ${d.url}`});await e.logs.create(n,h)}return r}function I3(t){return os(t,t.env.data)}async function Cp(t,e,n){return(await t.list(e,{page:0,per_page:10,include_totals:!1,q:`email:${n}`})).users}async function Yi({userAdapter:t,tenant_id:e,username:n,provider:r}){const i=r==="sms"?`phone_number:${n}`:`email:${n}`,{users:o}=await t.list(e,{page:0,per_page:10,include_totals:!1,q:`${i} provider:${r}`});return o.length>1&&console.error("More than one user found for same email and provider"),o[0]||null}async function zp({userAdapter:t,tenant_id:e,email:n}){var l;const{users:r}=await t.list(e,{page:0,per_page:10,include_totals:!1,q:`email:${n}`}),i=r.filter(u=>!(u.provider==="auth2"&&!u.email_verified));if(i.length===0)return;const o=i.filter(u=>!u.linked_to);if(o.length>0)return o.length>1&&console.error("More than one primary user found for same email"),o[0];const a=await t.get(e,(l=i[0])==null?void 0:l.linked_to);if(!a)throw new Error("Primary account not found");return a}async function Ro({userAdapter:t,tenant_id:e,username:n,provider:r}){const i=await Yi({userAdapter:t,tenant_id:e,username:n,provider:r});return i?i.linked_to?t.get(e,i.linked_to):i:null}async function Dc(t,e){const{username:n,provider:r,connection:i,client:o,userId:a,isSocial:l,profileData:u={},ip:d=""}=e;let p=await Ro({userAdapter:t.env.data.users,tenant_id:e.client.tenant.id,username:n,provider:r});if(!p){const h={user_id:`${r}|${a||zc()}`,email:i!=="sms"?n:void 0,phone_number:i==="sms"?n:void 0,name:n,provider:r,connection:i,email_verified:!0,last_ip:d,is_social:l,last_login:new Date().toISOString(),profileData:JSON.stringify(u)};p=await I3(t).users.create(o.tenant.id,h),t.set("user_id",p.user_id)}return p}const ot=s.z.object({page:s.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:s.z.string().min(1).optional().default("10").transform(t=>parseInt(t,10)).openapi({description:"The number of items per page"}),include_totals:s.z.string().optional().default("false").transform(t=>t==="true").openapi({description:"If the total number of items should be included in the response"}),sort:s.z.string().regex(/^.+:(-1|1)$/).optional().openapi({description:"A property that should have the format 'string:-1' or 'string:1'"}),q:s.z.string().optional().openapi({description:"A lucene query string used to filter the results"})});function vt(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 Ch=Ut.extend({users:s.z.array(kn)}),T3=Ut.extend({sessions:s.z.array(Nc)}),O3=Ut.extend({organizations:s.z.array(hr)}),D3=new s.OpenAPIHono().openapi(s.createRoute({tags:["users"],method:"get",path:"/",request:{query:ot,headers:s.z.object({"tenant-id":s.z.string()})},security:[{Bearer:["auth:read"]}],responses:{200:{content:{"application/json":{schema:s.z.union([s.z.array(kn),Ch])}},description:"List of users"}}}),async t=>{const{page:e,per_page:n,include_totals:r,sort:i,q:o}=t.req.valid("query"),{"tenant-id":a}=t.req.valid("header");if(o!=null&&o.includes("identities.profileData.email")){const p=o.split("=")[1],g=(await t.env.data.users.list(a,{page:e,per_page:n,include_totals:r,q:`email:${p}`})).users.filter(z=>z.linked_to),[$]=g;if(!$)return t.json([]);const A=await t.env.data.users.get(a,$.linked_to);if(!A)throw new E(500,{message:"Primary account not found"});return t.json([kn.parse(A)])}const l=["-_exists_:linked_to"];o&&l.push(o);const u=await t.env.data.users.list(a,{page:e,per_page:n,include_totals:r,sort:vt(i),q:l.join(" ")}),d=u.users.filter(p=>!p.linked_to);return r?t.json(Ch.parse({users:d,length:u.length,start:u.start,limit:u.limit})):t.json(s.z.array(kn).parse(d))}).openapi(s.createRoute({tags:["users"],method:"get",path:"/{user_id}",request:{headers:s.z.object({"tenant-id":s.z.string()}),params:s.z.object({user_id:s.z.string()})},security:[{Bearer:["auth:read"]}],responses:{200:{content:{"application/json":{schema:kn}},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 E(404);if(r.linked_to)throw new E(404,{message:"User is linked to another user"});return t.json(r)}).openapi(s.createRoute({tags:["users"],method:"delete",path:"/{user_id}",request:{headers:s.z.object({"tenant-id":s.z.string()}),params:s.z.object({user_id:s.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 E(404);return t.text("OK")}).openapi(s.createRoute({tags:["users"],method:"post",path:"/",request:{headers:s.z.object({"tenant-id":s.z.string()}),body:{content:{"application/json":{schema:s.z.object({...$a.shape})}}}},security:[{Bearer:["auth:write"]}],responses:{201:{content:{"application/json":{schema:kn}},description:"Status"}}}),async t=>{const{"tenant-id":e}=t.req.valid("header"),n=t.req.valid("json");t.set("body",n);const{email:r,phone_number:i,name:o,linked_to:a,email_verified:l,provider:u,connection:d}=n,p=`${n.provider}|${n.user_id||zc()}`;try{const h=await t.env.data.users.create(e,{email:r,user_id:p,name:o||r||i,phone_number:i,provider:u,connection:d,linked_to:a??void 0,email_verified:l||!1,last_ip:"",is_social:!1,last_login:new Date().toISOString()});t.set("user_id",h.user_id);const g=qe(t,{type:Fe.SUCCESS_API_OPERATION,description:"User created"});ln(t,t.env.data.logs.create(e,g));const $={...h,identities:[{connection:h.connection,provider:h.provider,user_id:_h(h.user_id),isSocial:h.is_social}]};return t.json(kn.parse($),{status:201})}catch(h){throw h.message==="User already exists"?new E(409,{message:"User already exists"}):h}}).openapi(s.createRoute({tags:["users"],method:"patch",path:"/{user_id}",request:{headers:s.z.object({"tenant-id":s.z.string()}),body:{content:{"application/json":{schema:s.z.object({...$a.shape,verify_email:s.z.boolean(),password:s.z.string()}).partial()}}},params:s.z.object({user_id:s.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:o,password:a,...l}=r,u=await e.users.get(n,i);if(!u)throw new E(404);if(l.email&&l.email!==u.email){const h=await Cp(t.env.data.users,n,l.email);if(h.length&&h.some(g=>g.user_id!==i))throw new E(409,{message:"Another user with the same email address already exists."})}if(u.linked_to)throw new E(404,{message:"User is linked to another user"});if(await t.env.data.users.update(n,i,l),a){const h=(p=u.identities)==null?void 0:p.find(A=>A.connection==="Username-Password-Authentication");if(!h)throw new E(400,{message:"User does not have a password identity"});const g={user_id:h.user_id,password:await is.hash(a,10),algorithm:"bcrypt"};await e.passwords.get(n,h.user_id)?await e.passwords.update(n,g):await e.passwords.create(n,g)}const d=await t.env.data.users.get(n,i);if(!d)throw new E(500);return t.json(d)}).openapi(s.createRoute({tags:["users"],method:"post",path:"/{user_id}/identities",request:{headers:s.z.object({"tenant-id":s.z.string()}),body:{content:{"application/json":{schema:s.z.union([s.z.object({link_with:s.z.string()}),s.z.object({user_id:s.z.string(),provider:s.z.string(),connection:s.z.string().optional()})])}}},params:s.z.object({user_id:s.z.string()})},security:[{Bearer:["auth:write"]}],responses:{201:{content:{"application/json":{schema:s.z.array(s.z.object({connection:s.z.string(),provider:s.z.string(),user_id:s.z.string(),isSocial:s.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,o=await t.env.data.users.get(e,r);if(!o)throw new E(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}`}),l=[o,...a.users].map(u=>({connection:u.connection,provider:u.provider,user_id:_h(u.user_id),isSocial:u.is_social}));return t.json(l,{status:201})}).openapi(s.createRoute({tags:["users"],method:"delete",path:"/{user_id}/identities/{provider}/{linked_user_id}",request:{headers:s.z.object({"tenant-id":s.z.string()}),params:s.z.object({user_id:s.z.string(),provider:s.z.string(),linked_user_id:s.z.string()})},security:[{Bearer:["auth:write"]}],responses:{200:{content:{"application/json":{schema:s.z.array(kn)}},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 o=await t.env.data.users.get(e,n);if(!o)throw new E(404);return t.json([kn.parse(o)])}).openapi(s.createRoute({tags:["users"],method:"get",path:"/{user_id}/sessions",request:{query:ot,headers:s.z.object({"tenant-id":s.z.string()}),params:s.z.object({user_id:s.z.string()})},security:[{Bearer:["auth:read"]}],responses:{200:{content:{"application/json":{schema:s.z.union([s.z.array(Nc),T3])}},description:"List of sessions"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{include_totals:n,page:r,per_page:i}=t.req.valid("query"),{"tenant-id":o}=t.req.valid("header"),a=await t.env.data.sessions.list(o,{page:r,per_page:i,include_totals:n,q:`user_id:${e}`});return n?t.json(a):t.json(a.sessions)}).openapi(s.createRoute({tags:["users"],method:"get",path:"/{user_id}/permissions",request:{params:s.z.object({user_id:s.z.string()}),headers:s.z.object({"tenant-id":s.z.string()}),query:ot},security:[{Bearer:["auth:read"]}],responses:{200:{content:{"application/json":{schema:v_}},description:"User permissions"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{"tenant-id":n}=t.req.valid("header"),{page:r,per_page:i,sort:o,q:a}=t.req.valid("query");if(!await t.env.data.users.get(n,e))throw new E(404,{message:"User not found"});const u=await t.env.data.userPermissions.list(n,e,{page:r,per_page:i,include_totals:!1,sort:vt(o),q:a});return t.json(u)}).openapi(s.createRoute({tags:["users"],method:"post",path:"/{user_id}/permissions",request:{params:s.z.object({user_id:s.z.string()}),headers:s.z.object({"tenant-id":s.z.string()}),body:{content:{"application/json":{schema:s.z.object({permissions:s.z.array(s.z.object({permission_name:s.z.string(),resource_server_identifier:s.z.string()}))})}}}},security:[{Bearer:["auth:write"]}],responses:{201:{description:"Permissions assigned to user"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{"tenant-id":n}=t.req.valid("header"),{permissions:r}=t.req.valid("json");if(!await t.env.data.users.get(n,e))throw new E(404,{message:"User not found"});for(const o of r)if(!await t.env.data.userPermissions.create(n,e,{user_id:e,resource_server_identifier:o.resource_server_identifier,permission_name:o.permission_name}))throw new E(500,{message:"Failed to assign permissions to user"});return t.json({message:"Permissions assigned successfully"},{status:201})}).openapi(s.createRoute({tags:["users"],method:"delete",path:"/{user_id}/permissions",request:{params:s.z.object({user_id:s.z.string()}),headers:s.z.object({"tenant-id":s.z.string()}),body:{content:{"application/json":{schema:s.z.object({permissions:s.z.array(s.z.object({permission_name:s.z.string(),resource_server_identifier:s.z.string()}))})}}}},security:[{Bearer:["auth:write"]}],responses:{200:{description:"Permissions removed from user"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{"tenant-id":n}=t.req.valid("header"),{permissions:r}=t.req.valid("json");if(!await t.env.data.users.get(n,e))throw new E(404,{message:"User not found"});for(const o of r)if(!await t.env.data.userPermissions.remove(n,e,o))throw new E(500,{message:"Failed to remove permissions from user"});return t.json({message:"Permissions removed successfully"})}).openapi(s.createRoute({tags:["users"],method:"get",path:"/{user_id}/roles",request:{params:s.z.object({user_id:s.z.string()}),headers:s.z.object({"tenant-id":s.z.string()})},security:[{Bearer:["auth:read"]}],responses:{200:{content:{"application/json":{schema:za}},description:"User roles"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{"tenant-id":n}=t.req.valid("header");if(!await t.env.data.users.get(n,e))throw new E(404,{message:"User not found"});const i=await t.env.data.userRoles.list(n,e,void 0,"");return t.json(i)}).openapi(s.createRoute({tags:["users"],method:"post",path:"/{user_id}/roles",request:{params:s.z.object({user_id:s.z.string()}),headers:s.z.object({"tenant-id":s.z.string()}),body:{content:{"application/json":{schema:s.z.object({roles:s.z.array(s.z.string())})}}}},security:[{Bearer:["auth:write"]}],responses:{201:{description:"Roles assigned to user"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{"tenant-id":n}=t.req.valid("header"),{roles:r}=t.req.valid("json");if(!await t.env.data.users.get(n,e))throw new E(404,{message:"User not found"});for(const o of r)if(!await t.env.data.userRoles.create(n,e,o,""))throw new E(500,{message:"Failed to assign roles to user"});return t.json({message:"Roles assigned successfully"},{status:201})}).openapi(s.createRoute({tags:["users"],method:"delete",path:"/{user_id}/roles",request:{params:s.z.object({user_id:s.z.string()}),headers:s.z.object({"tenant-id":s.z.string()}),body:{content:{"application/json":{schema:s.z.object({roles:s.z.array(s.z.string())})}}}},security:[{Bearer:["auth:write"]}],responses:{200:{description:"Roles removed from user"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{"tenant-id":n}=t.req.valid("header"),{roles:r}=t.req.valid("json");if(!await t.env.data.users.get(n,e))throw new E(404,{message:"User not found"});for(const o of r)if(!await t.env.data.userRoles.remove(n,e,o,""))throw new E(500,{message:"Failed to remove roles from user"});return t.json({message:"Roles removed successfully"})}).openapi(s.createRoute({tags:["users"],method:"get",path:"/{user_id}/organizations",request:{params:s.z.object({user_id:s.z.string()}),query:ot,headers:s.z.object({"tenant-id":s.z.string()})},security:[{Bearer:["auth:read"]}],responses:{200:{content:{"application/json":{schema:s.z.union([O3,s.z.array(hr)])}},description:"List of user organizations"}}}),async t=>{const{user_id:e}=t.req.valid("param"),{"tenant-id":n}=t.req.valid("header"),{page:r,per_page:i,include_totals:o,sort:a}=t.req.valid("query");if(!await t.env.data.users.get(n,e))throw new E(404,{message:"User not found"});const u=await t.env.data.userOrganizations.listUserOrganizations(n,e,{page:r,per_page:i,sort:vt(a)});return o?t.json({organizations:u.organizations,start:u.start,limit:u.limit,length:u.length}):t.json(u.organizations)}).openapi(s.createRoute({tags:["users"],method:"delete",path:"/{user_id}/organizations/{organization_id}",request:{params:s.z.object({user_id:s.z.string(),organization_id:s.z.string()}),headers:s.z.object({"tenant-id":s.z.string()})},security:[{Bearer:["auth:write"]}],responses:{200:{description:"User removed from organization successfully"}}}),async t=>{const{user_id:e,organization_id:n}=t.req.valid("param"),{"tenant-id":r}=t.req.valid("header");if(!await t.env.data.users.get(r,e))throw new E(404,{message:"User not found"});const a=(await t.env.data.userOrganizations.list(r,{q:`user_id:${e}`,per_page:100})).userOrganizations.find(l=>l.organization_id===n);if(!a)throw new E(404,{message:"User is not a member of this organization"});return await t.env.data.userOrganizations.remove(r,a.id),t.json({message:"User removed from organization successfully"})});/*! *****************************************************************************
|
|
73
73
|
Copyright (C) Microsoft. All rights reserved.
|
|
74
74
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
75
75
|
this file except in compliance with the License. You may obtain a copy of the
|
package/dist/authhero.mjs
CHANGED
|
@@ -6726,7 +6726,7 @@ async function Wb(t, e) {
|
|
|
6726
6726
|
let { user: n } = e;
|
|
6727
6727
|
const r = e.responseType || un.TOKEN;
|
|
6728
6728
|
if (e.loginSession && n && !e.skipHooks) {
|
|
6729
|
-
((i = n.app_metadata) == null ? void 0 : i.strategy) !== e.strategy && (n.app_metadata = { ...n.app_metadata, strategy: e.strategy }, await t.env.data.users.update(e.client.tenant.id, n.user_id, {
|
|
6729
|
+
e.strategy && ((i = n.app_metadata) == null ? void 0 : i.strategy) !== e.strategy && (n.app_metadata = { ...n.app_metadata, strategy: e.strategy }, await t.env.data.users.update(e.client.tenant.id, n.user_id, {
|
|
6730
6730
|
app_metadata: {
|
|
6731
6731
|
...n.app_metadata || {},
|
|
6732
6732
|
strategy: e.strategy
|