authhero 0.59.0 → 0.60.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 +35 -13
- package/package.json +1 -1
package/dist/authhero.cjs
CHANGED
|
@@ -146,7 +146,7 @@ PERFORMANCE OF THIS SOFTWARE.
|
|
|
146
146
|
}};
|
|
147
147
|
<\/script>
|
|
148
148
|
</body>
|
|
149
|
-
</html>`;return new Response(r,{headers:{"Content-Type":"text/html"}})}async function nv(n,e,t,i,r){var _,x,h;if(!t.redirect_uri)throw new j(400,{message:"Missing redirect_uri in authParams"});const[s]=await n.env.data.keys.list();if(!s)throw new j(500,{message:"No signing key found"});if(!((_=e.addons)!=null&&_.samlp))throw new j(400,{message:`SAML Addon is not enabled for client ${e.id}`});const{recipient:a,audience:c}=e.addons.samlp,l=t.state||"";if(!a||!l||!i||!t.state)throw new j(400,{message:"Missing recipient or inResponseTo"});const u=JSON.parse(t.state),p=new URL(t.redirect_uri),g=await iv(n,{issuer:n.env.ISSUER,audience:c||t.client_id,destination:p.toString(),inResponseTo:u.requestId,userId:((h=(x=i.app_metadata)==null?void 0:x.vimeo)==null?void 0:h.user_id)||i.user_id,email:i.email,sessionIndex:r,signature:{privateKeyPem:s.pkcs7,cert:s.cert,kid:s.kid}});return tv(p.toString(),g,u.relayState)}async function iv(n,e){const t=e.notBefore||new Date().toISOString(),i=e.notAfter||new Date(new Date(t).getTime()+10*60*1e3).toISOString(),r=e.issueInstant||t,s=e.sessionNotOnOrAfter||i,a=e.responseId||`_${Me()}`,c=e.assertionId||`_${Me()}`,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":i,"@_Recipient":e.destination}}],":@":{"@_Method":"urn:oasis:names:tc:SAML:2.0:cm:bearer"}}]},{"saml:Conditions":[{"saml:AudienceRestriction":[{"saml:Audience":[{"#text":e.audience}]}]}],":@":{"@_NotBefore":t,"@_NotOnOrAfter":i}},{"saml:AuthnStatement":[{"saml:AuthnContext":[{"saml:AuthnContextClassRef":[{"#text":"urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified"}]}]}],":@":{"@_AuthnInstant":r,"@_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":r,"@_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":r,"@_Version":"2.0"}}];let p=new ev.XMLBuilder({ignoreAttributes:!1,suppressEmptyNode:!0,preserveOrder:!0}).build(l);if(e.signature){const _=await fetch(n.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(!_.ok)throw new Error(`Failed to sign SAML response: ${_.status}`);p=await _.text()}return e.encode===!1?p:btoa(p)}const gd=["sub","iss","aud","exp","nbf","iat","jti"];async function Yc(n,e){var m,b;const{authParams:t,user:i,client:r,session_id:s}=e,c=(await n.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 j(500,{message:"No signing key available"});const u=Om(l.pkcs7),p={aud:t.audience||"default",scope:t.scope||"",sub:(i==null?void 0:i.user_id)||t.client_id,iss:n.env.ISSUER,tenant_id:n.var.tenant_id,sid:s},g=i&&((m=t.scope)!=null&&m.split(" ").includes("openid"))?{aud:t.client_id,sub:i.user_id,iss:n.env.ISSUER,sid:s,nonce:t.nonce,given_name:i.given_name,family_name:i.family_name,nickname:i.nickname,picture:i.picture,locale:i.locale,name:i.name,email:i.email,email_verified:i.email_verified}:void 0;(b=n.env.hooks)!=null&&b.onExecuteCredentialsExchange&&await n.env.hooks.onExecuteCredentialsExchange({client:r,user:i,scope:t.scope||"",grant_type:""},{accessToken:{setCustomClaim:(S,O)=>{if(gd.includes(S))throw new Error(`Cannot overwrite reserved claim '${S}'`);p[S]=O}},idToken:{setCustomClaim:(S,O)=>{if(gd.includes(S))throw new Error(`Cannot overwrite reserved claim '${S}'`);g&&(g[S]=O)}},access:{deny:S=>{throw new j(400,{message:`Access denied: ${S}`})}}});const _={includeIssuedTimestamp:!0,expiresIn:new qc(1,"d"),headers:{kid:l.kid}},x=await ld("RS256",u,p,_),h=g?await ld("RS256",u,g,_):void 0;return{access_token:x,refresh_token:e.refresh_token,id_token:h,token_type:"Bearer",expires_in:86400}}async function rv(n,e){const{client:t,scope:i,audience:r=t.tenant.audience,session_id:s}=e;return await n.env.data.refreshTokens.create(t.tenant.id,{id:Me(),session_id:s,client_id:t.id,expires_at:new Date(Date.now()+Hc*1e3).toISOString(),user_id:e.user.user_id,device:{last_ip:"",initial_ip:"",last_user_agent:"",initial_user_agent:"",initial_asn:"",last_asn:""},resource_servers:[{audience:r,scopes:i}],rotating:!1})}async function ch(n,e){const{user:t,client:i,scope:r,audience:s}=e,a=await n.env.data.sessions.create(i.tenant.id,{id:Me(),user_id:t.user_id,expires_at:new Date(Date.now()+Hc*1e3).toISOString(),used_at:new Date().toISOString(),device:{last_ip:n.req.header("x-real-ip")||"",initial_ip:n.req.header("x-real-ip")||"",last_user_agent:n.req.header("user-agent")||"",initial_user_agent:n.req.header("user-agent")||"",initial_asn:"",last_asn:""},clients:[i.id]}),c=r!=null&&r.split(" ").includes("offline_access")?await rv(n,{...e,session_id:a.id,scope:r,audience:s}):void 0;return{...a,refresh_token:c}}async function ei(n,e){var g;const{authParams:t,user:i,client:r}=e,s=be(n,{type:_e.SUCCESS_LOGIN,description:`Successful login for ${i.user_id}`,userId:i.user_id});_t(n,n.env.data.logs.create(r.tenant.id,s)),_t(n,n.env.data.users.update(r.tenant.id,i.user_id,{last_login:new Date().toISOString(),last_ip:n.req.header("x-real-ip")||"",login_count:i.login_count+1}));let a=e.refreshToken,c=e.sessionId;if(!c){const _=await ch(n,{user:i,client:r,scope:t.scope,audience:t.audience});c=_.id,a=(g=_.refresh_token)==null?void 0:g.id}if(e.authParams.response_mode===Vt.SAML_POST)return nv(n,e.client,e.authParams,i,c);const l=await Yc(n,{authParams:t,user:i,client:r,session_id:c,refresh_token:a}),u=new Headers({"set-cookie":eh(r.tenant.id,c)});if(t.response_mode===Vt.WEB_MESSAGE)return n.json(l,{headers:u});if((t.response_type||Ut.CODE)===Ut.CODE){if(!e.loginSession)throw new j(500,{message:"Login session not found"});const _=await n.env.data.codes.create(r.tenant.id,{code_id:Me(),user_id:i.user_id,code_type:"authorization_code",login_id:e.loginSession.login_id,expires_at:new Date(Date.now()+F0*1e3).toISOString()});u.set("location",`${t.redirect_uri}?state=${e.authParams.state}&code=${_.code_id}`)}return new Response("Redirecting",{status:302,headers:u})}function sv(n){return async(e,t)=>{if(!t.email||!t.email_verified)return n.users.create(e,t);const i=await Kd({userAdapter:n.users,tenant_id:e,email:t.email});return i?(await n.users.create(e,{...t,linked_to:i.user_id}),i):n.users.create(e,t)}}async function lh(n,e,t){for await(const i of e)if(!(await fetch(i.url,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})).ok){const s=be(n,{type:_e.FAILED_LOGIN_INCORRECT_PASSWORD,description:"Invalid password"});await t.logs.create(n.var.tenant_id,s)}}function ov(n,e){return async(t,i)=>{const{hooks:r}=await e.hooks.list(t);return await lh(n,r,{tenant_id:t,user:i,trigger_id:"post-user-registration"}),i}}function av(n,e){return async(t,i)=>{const{hooks:r}=await e.hooks.list(t,{q:"trigger_id:pre-user-signup",page:0,per_page:100,include_totals:!1});await lh(n,r,{tenant_id:t,email:i,trigger_id:"pre-user-signup"})}}function cv(n,e){return async(t,i)=>{let r=await sv(e)(t,i);return await ov(n,e)(t,r),r}}async function lv(n,e,t,i){if(e.disable_sign_ups&&!await Kd({userAdapter:n.env.data.users,tenant_id:e.tenant.id,email:i})){const s=be(n,{type:_e.FAILED_SIGNUP,description:"Public signup is disabled"});throw await n.env.data.logs.create(e.tenant.id,s),new j(400,{message:"Signups are disabled for this client"})}await av(n,t)(n.var.tenant_id||"",i)}function uv(n,e){return{...e,users:{...e.users,create:cv(n,e)}}}async function dv(n,e,t,i){if(!i.state)throw new j(400,{message:"State not found"});const r=e.connections.find(l=>l.name===t);if(!r){n.set("client_id",e.id);const l=be(n,{type:_e.FAILED_LOGIN,description:"Connection not found"});throw await n.env.data.logs.create(e.tenant.id,l),new j(403,{message:"Connection Not Found"})}let s=await n.env.data.logins.get(e.tenant.id,i.state);s||(s=await n.env.data.logins.create(e.tenant.id,{expires_at:new Date(Date.now()+es*1e3).toISOString(),authParams:i,...Hn(n.req)}));const c=await Yf(n,r.strategy).getRedirect(n,r);return await n.env.data.codes.create(e.tenant.id,{login_id:s.login_id,code_id:c.code,code_type:"oauth2_state",connection_id:r.id,code_verifier:c.codeVerifier,expires_at:new Date(Date.now()+K0*1e3).toISOString()}),n.redirect(c.redirectUrl)}async function _d(n,{code:e,state:t}){var h;const{env:i}=n,r=await i.data.codes.get(n.var.tenant_id||"",t,"oauth2_state");if(!r||!r.connection_id)throw new j(403,{message:"State not found"});const s=await i.data.logins.get(n.var.tenant_id||"",r.login_id);if(!s)throw new j(403,{message:"Session not found"});const a=await Kc(i,s.authParams.client_id);n.set("client_id",a.id),n.set("tenant_id",a.tenant.id);const c=a.connections.find(m=>m.id===r.connection_id);if(!c){const m=be(n,{type:_e.FAILED_LOGIN,description:"Connection not found"});throw await i.data.logs.create(a.tenant.id,m),new j(403,{message:"Connection not found"})}if(n.set("connection",c.name),!s.authParams.redirect_uri){const m=be(n,{type:_e.FAILED_LOGIN,description:"Redirect URI not defined"});throw await i.data.logs.create(a.tenant.id,m),new j(403,{message:"Redirect URI not defined"})}if(!Xs(s.authParams.redirect_uri,a.callbacks||[],{allowPathWildcards:!0})){const m=`Invalid redirect URI - ${s.authParams.redirect_uri}`,b=be(n,{type:_e.FAILED_LOGIN,description:m});throw await i.data.logs.create(a.tenant.id,b),new j(403,{message:m})}const u=await Yf(n,c.strategy).validateAuthorizationCodeAndGetUser(n,c,e,r.code_verifier),{sub:p,...g}=u;n.set("user_id",p);const _=((h=u.email)==null?void 0:h.toLocaleLowerCase())||`${c.name}.${p}@${new URL(n.env.ISSUER).hostname}`;n.set("username",_);let x=await as({userAdapter:i.data.users,tenant_id:a.tenant.id,email:_,provider:c.name});if(!x){try{await lv(n,a,n.env.data,_)}catch(m){const b=m;throw new j(500,{message:`Failed to run preUserSignupHook: ${b.message}`})}x=await i.data.users.create(a.tenant.id,{user_id:`${c.name}|${p}`,email:_,name:_,provider:c.name,connection:c.name,email_verified:!0,last_ip:"",is_social:!0,last_login:new Date().toISOString(),profileData:JSON.stringify(g)}),n.set("user_id",x.user_id)}return ei(n,{client:a,authParams:s.authParams,loginSession:s,user:x})}async function md(n,e,t,i,r,s){const a=await n.env.data.codes.get(n.var.tenant_id||"",e,"oauth2_state");if(!a)throw new j(400,{message:"State not found"});const c=await n.env.data.logins.get(n.var.tenant_id,a.login_id);if(!c)throw new j(400,{message:"Login not found"});const{redirect_uri:l}=c.authParams;if(!l)throw new j(400,{message:"Redirect uri not found"});const u=be(n,{type:_e.FAILED_LOGIN,description:`Failed connection login: ${r} ${t}, ${i}`});_t(n,n.env.data.logs.create(n.var.tenant_id,u));const p=new URL(l);return D0(p,{error:t,error_description:i,error_reason:s,error_code:r,state:c.authParams.state}),n.redirect(`${vt(n.env)}enter-email?state=${c.login_id}&error=${t}`)}const pv=new o.OpenAPIHono().openapi(o.createRoute({tags:["oauth2"],method:"get",path:"/",request:{query:o.z.object({state:o.z.string(),code:o.z.string().optional(),scope:o.z.string().optional(),hd:o.z.string().optional(),error:o.z.string().optional(),error_description:o.z.string().optional(),error_code:o.z.string().optional(),error_reason:o.z.string().optional()})},responses:{302:{description:"Redirect to the client's redirect uri"}}}),async n=>{const{state:e,code:t,error:i,error_description:r,error_code:s,error_reason:a}=n.req.valid("query");if(i)return md(n,e,i,r,s,a);if(!t)throw new j(400,{message:"Code is required"});return _d(n,{code:t,state:e})}).openapi(o.createRoute({tags:["oauth2"],method:"post",path:"/",request:{body:{content:{"application/x-www-form-urlencoded":{schema:o.z.object({state:o.z.string(),code:o.z.string().optional(),scope:o.z.string().optional(),hd:o.z.string().optional(),error:o.z.string().optional(),error_description:o.z.string().optional(),error_code:o.z.string().optional(),error_reason:o.z.string().optional()})}}}},responses:{302:{description:"Redirect to the client's redirect uri"}}}),async n=>{const{state:e,code:t,error:i,error_description:r,error_code:s,error_reason:a}=n.req.valid("form");if(i)return md(n,e,i,r,s,a);if(!t)throw new j(400,{message:"Code is required"});return _d(n,{code:t,state:e})}),fv=new o.OpenAPIHono().openapi(o.createRoute({tags:["oauth2"],method:"get",path:"/",request:{query:o.z.object({client_id:o.z.string(),returnTo:o.z.string().optional()}),header:o.z.object({cookie:o.z.string().optional()})},responses:{302:{description:"Log the user out"}}}),async n=>{const{client_id:e,returnTo:t}=n.req.valid("query"),i=await n.env.data.clients.get(e);if(!i)return n.text("OK");const r=await n.env.data.clients.get("DEFAULT_CLIENT");n.set("client_id",e),n.set("tenant_id",i.tenant.id);const s=t||n.req.header("referer");if(!s)return n.text("OK");if(!Xs(s,[...i.allowed_logout_urls||[],...(r==null?void 0:r.allowed_logout_urls)||[]],{allowPathWildcards:!0}))throw new j(400,{message:"Invalid redirect uri"});const a=n.req.header("cookie");if(a){const l=Qf(i.tenant.id,a);if(l){const u=await n.env.data.sessions.get(i.tenant.id,l);if(u){const p=await n.env.data.users.get(i.tenant.id,u.user_id);p&&(n.set("user_id",p.user_id),n.set("connection",p.connection))}await n.env.data.sessions.remove(i.tenant.id,l)}}const c=be(n,{type:_e.SUCCESS_LOGOUT,description:"User successfully logged out"});return await n.env.data.logs.create(i.tenant.id,c),new Response("Redirecting",{status:302,headers:{"set-cookie":Rm(i.tenant.id),location:s}})}),yd=o.z.object({sub:o.z.string(),email:o.z.string().optional(),family_name:o.z.string().optional(),given_name:o.z.string().optional(),email_verified:o.z.boolean()}),hv=new o.OpenAPIHono().openapi(o.createRoute({tags:["oauth2"],method:"get",path:"/",request:{},security:[{Bearer:["openid"]}],responses:{200:{content:{"application/json":{schema:yd}},description:"Userinfo"}}}),async n=>{if(!n.var.user)throw new j(404,{message:"User not found"});const e=await n.env.data.users.get(n.var.user.tenant_id,n.var.user.sub);if(!e)throw new j(404,{message:"User not found"});return n.json(yd.parse({...e,sub:e.user_id}))}),gv=new o.OpenAPIHono().openapi(o.createRoute({tags:["well known"],method:"get",path:"/jwks.json",request:{},responses:{200:{content:{"application/json":{schema:jd}},description:"List of tenants"}}}),async n=>{const e=await n.env.data.keys.list(),t=await Promise.all(e.map(async i=>{const s=await new Mc(i.cert).publicKey.export(),a=await crypto.subtle.exportKey("jwk",s);return Ga.parse({...a,kid:i.kid})}));return n.json({keys:t},{headers:{"access-control-allow-origin":"*","access-control-allow-method":"GET","cache-control":`public, max-age=${er}, stale-while-revalidate=${er*2}, stale-if-error=86400`}})}).openapi(o.createRoute({tags:["well known"],method:"get",path:"/openid-configuration",request:{},responses:{200:{content:{"application/json":{schema:ko}},description:"List of tenants"}}}),async n=>{const e=ko.parse({issuer:vm(n.env),authorization_endpoint:`${Ie(n.env)}authorize`,token_endpoint:`${Ie(n.env)}oauth/token`,device_authorization_endpoint:`${Ie(n.env)}oauth/device/code`,userinfo_endpoint:`${Ie(n.env)}userinfo`,mfa_challenge_endpoint:`${Ie(n.env)}mfa/challenge`,jwks_uri:`${Ie(n.env)}.well-known/jwks.json`,registration_endpoint:`${Ie(n.env)}oidc/register`,revocation_endpoint:`${Ie(n.env)}oauth/revoke`,scopes_supported:["openid","profile","offline_access","name","given_name","family_name","nickname","email","email_verified","picture","created_at","identities","phone","address"],response_types_supported:["code","token","id_token","code token","code id_token","token id_token","code token id_token"],code_challenge_methods_supported:["S256","plain"],response_modes_supported:["query","fragment","form_post"],subject_types_supported:["public"],id_token_signing_alg_values_supported:["RS256"],token_endpoint_auth_methods_supported:["client_secret_basic","client_secret_post"],claims_supported:["aud","auth_time","created_at","email","email_verified","exp","family_name","given_name","iat","identities","iss","name","nickname","phone_number","picture","sub"],request_uri_parameter_supported:!1,request_parameter_supported:!1,token_endpoint_auth_signing_alg_values_supported:["RS256","RS384","PS256"]});return n.json(e,{headers:{"access-control-allow-origin":"*","access-control-allow-method":"GET","cache-control":`public, max-age=${er}, stale-while-revalidate=${er*2}, stale-if-error=86400`}})});function cr(n,e){if(!n||!e||n.length!==e.length)return!1;let t=0;for(let i=0;i<n.length;i++)t|=n.charCodeAt(i)^e.charCodeAt(i);return t===0}const uh=o.z.object({grant_type:o.z.literal("client_credentials"),scope:o.z.string().optional(),client_secret:o.z.string(),client_id:o.z.string(),audience:o.z.string().optional()});async function _v(n,e){const t=await n.env.data.clients.get(e.client_id);if(!t)throw new j(403,{message:"Invalid client credentials"});if(t.client_secret&&!cr(t.client_secret,e.client_secret))throw new j(403,{message:"Invalid client credentials"});const i={client_id:t.id,scope:e.scope,audience:e.audience},r=await Yc(n,{authParams:i,client:t});return n.json(r)}const mv=o.z.object({grant_type:o.z.literal("authorization_code"),client_id:o.z.string(),code:o.z.string(),redirect_uri:o.z.string().optional(),client_secret:o.z.string().optional(),code_verifier:o.z.string().optional()}).refine(n=>"client_secret"in n&&!("code_verifier"in n)||!("client_secret"in n)&&"code_verifier"in n,{message:"Must provide either client_secret (standard flow) or code_verifier/code_verifier_mode (PKCE flow), but not both"});async function yv(n,e){const t=await n.env.data.clients.get(e.client_id);if(!t)throw new j(403,{message:"Client not found"});const i=await n.env.data.codes.get(t.tenant.id,e.code,"authorization_code");if(!i||!i.user_id)throw new j(403,{message:"Invalid client credentials"});if(new Date(i.expires_at)<new Date)throw new j(403,{message:"Code expired"});if(i.used_at)throw new j(403,{message:"Code already used"});const r=await n.env.data.logins.get(t.tenant.id,i.login_id);if(!r)throw new j(403,{message:"Invalid login"});if("client_secret"in e){const a=await n.env.data.clients.get("DEFAULT_CLIENT");if(!cr(t.client_secret,e.client_secret)&&!cr(a==null?void 0:a.client_secret,e.client_secret))throw new j(403,{message:"Invalid client credentials"})}else if("code_verifier"in e&&typeof e.code_verifier=="string"&&"code_challenge_method"in r.authParams&&typeof r.authParams.code_challenge_method=="string"){const a=await Bm(e.code_verifier,r.authParams.code_challenge_method);if(!cr(a,r.authParams.code_challenge||""))throw new j(403,{message:"Invalid client credentials"})}if(r.authParams.redirect_uri&&r.authParams.redirect_uri!==e.redirect_uri)throw new j(403,{message:"Invalid redirect uri"});const s=await n.env.data.users.get(t.tenant.id,i.user_id);if(!s)throw new j(403,{message:"User not found"});return await n.env.data.codes.used(t.tenant.id,e.code),ei(n,{user:s,client:t,loginSession:r,authParams:{...r.authParams,response_mode:Vt.WEB_MESSAGE}})}const vv=o.z.object({grant_type:o.z.literal("refresh_token"),client_id:o.z.string(),redirect_uri:o.z.string().optional(),refresh_token:o.z.string()});async function wv(n,e){const t=await n.env.data.clients.get(e.client_id);if(!t)throw new j(403,{message:"Client not found"});const i=await n.env.data.refreshTokens.get(t.tenant.id,e.refresh_token);if(i){if(i.expires_at&&new Date(i.expires_at)<new Date)throw new j(403,{message:"Refresh token expired"})}else throw new j(403,{message:"Invalid refresh token"});const r=await n.env.data.sessions.get(t.tenant.id,i.session_id);if(!r)throw new j(403,{message:"Session not found"});const s=await n.env.data.users.get(t.tenant.id,r.user_id);if(!s)throw new j(403,{message:"User not found"});const a=i.resource_servers[0];return ei(n,{user:s,client:t,refreshToken:i.id,sessionId:r.id,authParams:{client_id:t.id,audience:a==null?void 0:a.audience,scope:a==null?void 0:a.scopes,response_mode:Vt.WEB_MESSAGE}})}const vd=o.z.object({client_id:o.z.string().optional(),client_secret:o.z.string().optional()}),bv=o.z.union([uh.extend(vd.shape),o.z.object({grant_type:o.z.literal("authorization_code"),client_id:o.z.string(),code:o.z.string(),redirect_uri:o.z.string(),code_verifier:o.z.string().min(43).max(128)}),o.z.object({grant_type:o.z.literal("authorization_code"),code:o.z.string(),redirect_uri:o.z.string().optional(),...vd.shape}),o.z.object({grant_type:o.z.literal("refresh_token"),client_id:o.z.string(),refresh_token:o.z.string(),redirect_uri:o.z.string().optional()})]);function kv(n){if(!n)return{};const[e,t]=n.split(" ");if((e==null?void 0:e.toLowerCase())==="basic"&&t){const[i,r]=atob(t).split(":");return{client_id:i,client_secret:r}}return{}}const xv=new o.OpenAPIHono().openapi(o.createRoute({tags:["oauth2"],method:"post",path:"/",request:{body:{content:{"application/x-www-form-urlencoded":{schema:bv}}}},responses:{200:{content:{"application/json":{schema:Pd}},description:"Tokens"}}}),async n=>{const e=n.req.valid("form"),t=kv(n.req.header("Authorization")),i={...e,...t};if(!i.client_id)throw new j(400,{message:"client_id is required"});switch(e.grant_type){case ci.AuthorizationCode:return yv(n,mv.parse(i));case ci.ClientCredential:return _v(n,uh.parse(i));case ci.RefreshToken:return wv(n,vv.parse(i));default:throw new j(400,{message:"Not implemented"})}});var Xc={exports:{}};const Qc=[{id:0,value:"Too weak",minDiversity:0,minLength:0},{id:1,value:"Weak",minDiversity:2,minLength:6},{id:2,value:"Medium",minDiversity:4,minLength:8},{id:3,value:"Strong",minDiversity:4,minLength:10}],dh=(n,e=Qc,t="!\"#$%&'()*+,-./:;<=>?@[\\\\\\]^_`{|}~")=>{let i=n||"";e[0].minDiversity=0,e[0].minLength=0;const r=[{regex:"[a-z]",message:"lowercase"},{regex:"[A-Z]",message:"uppercase"},{regex:"[0-9]",message:"number"}];t&&r.push({regex:`[${t}]`,message:"symbol"});let s={};s.contains=r.filter(c=>new RegExp(`${c.regex}`).test(i)).map(c=>c.message),s.length=i.length;let a=e.filter(c=>s.contains.length>=c.minDiversity).filter(c=>s.length>=c.minLength).sort((c,l)=>l.id-c.id).map(c=>({id:c.id,value:c.value}));return Object.assign(s,a[0]),s};Xc.exports={passwordStrength:dh,defaultOptions:Qc};var Sv=Xc.exports.passwordStrength=dh;Xc.exports.defaultOptions=Qc;function Av(n){return Sv(n).id<2?!1:n.length>=8&&/[a-z]/.test(n)&&/[A-Z]/.test(n)&&/[0-9]/.test(n)&&/[^A-Za-z0-9]/.test(n)}async function eo(n,e){var r;const t=await n.env.data.emailProviders.get(n.var.tenant_id)||(n.env.DEFAULT_TENANT_ID?await n.env.data.emailProviders.get(n.env.DEFAULT_TENANT_ID):null);if(!t)throw new j(500,{message:"Email provider not found"});const i=(r=n.env.emailProviders)==null?void 0:r[t.name];if(!i)throw new j(500,{message:"Email provider not found"});await i({emailProvider:t,...e,from:t.default_from_address||`login@${n.env.ISSUER}`})}async function Iv(n,e,t,i){const r=await n.env.data.tenants.get(n.var.tenant_id);if(!r)throw new j(500,{message:"Tenant not found"});const s=`${vt(n.env)}reset-password?state=${i}&code=${t}`,a={vendorName:r.name,lng:r.language||"en"};await eo(n,{to:e,subject:"Reset your password",html:`Click here to reset your password: ${vt(n.env)}reset-password?state=${i}&code=${t}`,template:"auth-password-reset",data:{vendorName:r.name,logo:r.logo||"",passwordResetUrl:s,supportUrl:r.support_url||"https://support.sesamy.com",buttonColor:r.primary_color||"#7d68f4",passwordResetTitle:ue("password_reset_title",a),resetPasswordEmailClickToReset:ue("reset_password_email_click_to_reset",a),resetPasswordEmailReset:ue("reset_password_email_reset",a),supportInfo:ue("support_info",a),contactUs:ue("contact_us",a),copyright:ue("copyright",a)}})}async function Ev(n,e,t){const i=await n.env.data.tenants.get(n.var.tenant_id);if(!i)throw new j(500,{message:"Tenant not found"});const r={vendorName:i.name,code:t,lng:i.language||"en"};await eo(n,{to:e,subject:ue("code_email_subject",r),html:`Click here to validate your email: ${vt(n.env)}validate-email`,template:"auth-link",data:{code:t,vendorName:i.name,logo:i.logo||"",supportUrl:i.support_url||"",magicLink:`${Ie(n.env)}passwordless/verify_redirect?ticket=${t}`,buttonColor:i.primary_color||"",welcomeToYourAccount:ue("welcome_to_your_account",r),linkEmailClickToLogin:ue("link_email_click_to_login",r),linkEmailLogin:ue("link_email_login",r),linkEmailOrEnterCode:ue("link_email_or_enter_code",r),codeValid30Mins:ue("code_valid_30_minutes",r),supportInfo:ue("support_info",r),contactUs:ue("contact_us",r),copyright:ue("copyright",r)}});const s=be(n,{type:_e.CODE_LINK_SENT,description:e});_t(n,n.env.data.logs.create(i.id,s))}async function ph(n,e,t){const i=await n.env.data.tenants.get(n.var.tenant_id);if(!i)throw new j(500,{message:"Tenant not found"});const r={vendorName:i.name,code:t,lng:i.language||"en"};await eo(n,{to:e,subject:ue("code_email_subject",r),html:`Click here to validate your email: ${vt(n.env)}validate-email`,template:"auth-link",data:{code:t,vendorName:i.name,logo:i.logo||"",supportUrl:i.support_url||"",magicLink:`${Ie(n.env)}passwordless/verify_redirect?ticket=${t}`,buttonColor:i.primary_color||"",welcomeToYourAccount:ue("welcome_to_your_account",r),linkEmailClickToLogin:ue("link_email_click_to_login",r),linkEmailLogin:ue("link_email_login",r),linkEmailOrEnterCode:ue("link_email_or_enter_code",r),codeValid30Mins:ue("code_valid_30_minutes",r),supportInfo:ue("support_info",r),contactUs:ue("contact_us",r),copyright:ue("copyright",r)}});const s=be(n,{type:_e.CODE_LINK_SENT,description:e});_t(n,n.env.data.logs.create(i.id,s))}async function fh(n,e){const t=await n.env.data.tenants.get(n.var.tenant_id);if(!t)throw new j(500,{message:"Tenant not found"});const i={vendorName:t.name,lng:t.language||"en"};await eo(n,{to:e.email,subject:"Validate your email address",html:`Click here to validate your email: ${vt(n.env)}validate-email`,template:"auth-verify-email",data:{vendorName:t.name,logo:t.logo||"",emailValidationUrl:`${vt(n.env)}validate-email`,supportUrl:t.support_url||"https://support.sesamy.com",buttonColor:t.primary_color||"#7d68f4",welcomeToYourAccount:ue("welcome_to_your_account",i),verifyEmailVerify:ue("verify_email_verify",i),supportInfo:ue("support_info",i),contactUs:ue("contact_us",i),copyright:ue("copyright",i)}})}const zv=new o.OpenAPIHono().openapi(o.createRoute({tags:["dbconnections"],method:"post",path:"/signup",request:{body:{content:{"application/json":{schema:o.z.object({client_id:o.z.string(),connection:o.z.literal("Username-Password-Authentication"),email:o.z.string().transform(n=>n.toLowerCase()),password:o.z.string()})}}}},responses:{200:{content:{"application/json":{schema:o.z.object({_id:o.z.string(),email:o.z.string(),email_verified:o.z.boolean(),app_metadata:o.z.object({}),user_metadata:o.z.object({})})}},description:"Created user"}}}),async n=>{const{email:e,password:t,client_id:i}=n.req.valid("json"),r=await n.env.data.clients.get(i);if(!r)throw new j(400,{message:"Client not found"});if(n.set("client_id",r.id),n.set("tenant_id",r.tenant.id),!Av(t))throw new j(400,{message:"Password does not meet the requirements"});if(await as({userAdapter:n.env.data.users,tenant_id:r.tenant.id,email:e,provider:"auth2"}))throw new j(400,{message:"Invalid sign up"});const a=await n.env.data.users.create(r.tenant.id,{user_id:`auth2|${Ya()}`,email:e,email_verified:!1,provider:"auth2",connection:"Username-Password-Authentication",is_social:!1});n.set("user_id",a.user_id),n.set("username",a.email),n.set("connection",a.connection);const c=await Za.hash(t,10);await n.env.data.passwords.create(r.tenant.id,{user_id:a.user_id,password:c,algorithm:"bcrypt"}),await fh(n,a);const l=be(n,{type:_e.SUCCESS_SIGNUP,description:"Successful signup"});return await n.env.data.logs.create(r.tenant.id,l),n.json({_id:a.user_id,email:a.email,email_verified:!1,app_metadata:{},user_metadata:{}})}).openapi(o.createRoute({tags:["dbconnections"],method:"post",path:"/change_password",request:{body:{content:{"application/json":{schema:o.z.object({client_id:o.z.string(),connection:o.z.literal("Username-Password-Authentication"),email:o.z.string().transform(n=>n.toLowerCase())})}}}},responses:{200:{description:"Redirect to the client's redirect uri"}}}),async n=>{const{email:e,client_id:t}=n.req.valid("json"),i=await n.env.data.clients.get(t);if(!i)throw new j(400,{message:"Client not found"});if(n.set("client_id",i.id),n.set("tenant_id",i.tenant.id),!await Xa({userAdapter:n.env.data.users,tenant_id:i.tenant.id,email:e,provider:"auth2"}))return n.html("If an account with that email exists, we've sent instructions to reset your password.");const s={client_id:t,username:e},a=await n.env.data.logins.create(i.tenant.id,{expires_at:new Date(Date.now()+es*1e3).toISOString(),authParams:s,...Hn(n.req)});return await Iv(n,e,a.login_id,a.authParams.state),n.html("If an account with that email exists, we've sent instructions to reset your password.")});function hh(){const n="1234567890";let e="";for(let t=0;t<6;t+=1)e+=n[Math.floor(Math.random()*10)];return e.toString()}const $v=new o.OpenAPIHono().openapi(o.createRoute({tags:["passwordless"],method:"post",path:"/start",request:{body:{content:{"application/json":{schema:o.z.object({client_id:o.z.string(),connection:o.z.string(),email:o.z.string().transform(n=>n.toLowerCase()),send:o.z.enum(["link","code"]),authParams:Wa.omit({client_id:!0})})}}}},responses:{200:{description:"Status"}}}),async n=>{const e=n.req.valid("json"),{env:t}=n,{client_id:i,email:r,send:s,authParams:a}=e,c=await n.env.data.clients.get(i);if(!c)throw new j(400,{message:"Client not found"});n.set("client_id",c.id),n.set("tenant_id",c.tenant.id);const l=await t.data.logins.create(c.tenant.id,{authParams:{...a,client_id:i,username:r},expires_at:new Date(Date.now()+ed).toISOString(),...Hn(n.req)}),u=await t.data.codes.create(c.tenant.id,{code_id:hh(),code_type:"otp",login_id:l.login_id,expires_at:new Date(Date.now()+ed).toISOString()});return s==="link"?await ph(n,r,u.code_id):await Ev(n,r,u.code_id),n.html("OK")}).openapi(o.createRoute({tags:["passwordless"],method:"get",path:"/verify_redirect",request:{query:o.z.object({scope:o.z.string(),response_type:o.z.nativeEnum(Ut),redirect_uri:o.z.string(),state:o.z.string(),nonce:o.z.string().optional(),verification_code:o.z.string(),connection:o.z.string(),client_id:o.z.string(),email:o.z.string().transform(n=>n.toLowerCase()),audience:o.z.string().optional()})},responses:{302:{description:"Status"}}}),async n=>{const{env:e}=n,{client_id:t,email:i,verification_code:r,redirect_uri:s,state:a,scope:c,audience:l,response_type:u,nonce:p}=n.req.valid("query"),g=await Kc(e,t);n.set("client_id",g.id),n.set("tenant_id",g.tenant.id),n.set("connection","email");const _=await e.data.codes.get(g.tenant.id,r,"otp");if(!_)throw new j(400,{message:"Code not found or expired"});if(_.expires_at<new Date().toISOString())throw new j(400,{message:"Code expired"});const x=await e.data.logins.get(g.tenant.id,_.login_id);if(!x||x.authParams.username!==i)throw new j(400,{message:"Code not found or expired"});const h=Hn(n.req);if(x.ip!==h.ip)return n.redirect(`${vt(n.env)}invalid-session?state=${x.login_id}`);if(!Xs(s,g.callbacks,{allowPathWildcards:!0}))throw new j(400,{message:`Invalid redirect URI - ${s}`});const m={client_id:t,redirect_uri:s,state:a,nonce:p,scope:c,audience:l,response_type:u},b=await as({userAdapter:e.data.users,tenant_id:g.tenant.id,email:i,provider:"email"});if(!b)throw new j(400,{message:"User not found"});return ei(n,{user:b,client:g,loginSession:x,authParams:m})});class oi extends j{constructor(t,i){super(t,i);te(this,"_code");this._code=i==null?void 0:i.code}get code(){return this._code}}async function Cv(n,e,t){const{env:i}=n,r=t.username;if(n.set("username",r),!r)throw new j(400,{message:"Username is required"});const s=await Xa({userAdapter:n.env.data.users,tenant_id:e.tenant.id,email:r,provider:"auth2"});if(!s){const _=be(n,{type:_e.FAILED_LOGIN_INCORRECT_PASSWORD,description:"Invalid user"});throw _t(n,n.env.data.logs.create(e.tenant.id,_)),new oi(403,{message:"User not found",code:"USER_NOT_FOUND"})}const a=s.linked_to?await i.data.users.get(e.tenant.id,s.linked_to):s;if(!a)throw new oi(403,{message:"User not found",code:"USER_NOT_FOUND"});n.set("connection",s.connection),n.set("user_id",a.user_id);const{password:c}=await i.data.passwords.get(e.tenant.id,s.user_id);if(!await Za.compare(t.password,c)){const _=be(n,{type:_e.FAILED_LOGIN_INCORRECT_PASSWORD,description:"Invalid password"});throw _t(n,n.env.data.logs.create(e.tenant.id,_)),new oi(403,{message:"Invalid password",code:"INVALID_PASSWORD"})}if((await i.data.logs.list(e.tenant.id,{page:0,per_page:10,include_totals:!1,q:`user_id:${a.user_id}`})).logs.filter(_=>_.type===_e.FAILED_LOGIN_INCORRECT_PASSWORD&&new Date(_.date)>new Date(Date.now()-1e3*60*5)).length>=3){const _=be(n,{type:_e.FAILED_LOGIN,description:"Too many failed login attempts"});throw _t(n,n.env.data.logs.create(e.tenant.id,_)),new oi(403,{message:"Too many failed login attempts",code:"TOO_MANY_FAILED_LOGINS"})}if(!s.email_verified&&e.email_validation==="enforced"){await fh(n,s);const _=be(n,{type:_e.FAILED_LOGIN,description:"Email not verified"});throw await n.env.data.logs.create(e.tenant.id,_),new oi(403,{message:"Email not verified",code:"EMAIL_NOT_VERIFIED"})}const g=be(n,{type:_e.SUCCESS_LOGIN,description:"Successful login",strategy_type:"Username-Password-Authentication",strategy:"Username-Password-Authentication"});return _t(n,n.env.data.logs.create(e.tenant.id,g)),a}function jv(){const n=new Uint8Array(32);return crypto.getRandomValues(n),sn.encode(n,{includePadding:!1})}function wd(){return new j(403,{res:new Response(JSON.stringify({error:"access_denied",error_description:"Wrong email or verification code."}),{status:403,headers:{"Content-Type":"application/json"}}),message:"Wrong email or verification code."})}const bd=30*60*1e3,Nv=new o.OpenAPIHono().openapi(o.createRoute({tags:["oauth"],method:"post",path:"/",request:{body:{content:{"application/json":{schema:o.z.union([o.z.object({credential_type:o.z.literal("http://auth0.com/oauth/grant-type/passwordless/otp"),otp:o.z.string(),client_id:o.z.string(),username:o.z.string().transform(n=>n.toLowerCase()),realm:o.z.enum(["email"]),scope:o.z.string().optional()}),o.z.object({credential_type:o.z.literal("http://auth0.com/oauth/grant-type/password-realm"),client_id:o.z.string(),username:o.z.string().transform(n=>n.toLowerCase()),password:o.z.string(),realm:o.z.enum(["Username-Password-Authentication"]),scope:o.z.string().optional()})])}}}},responses:{200:{description:"List of tenants"}}}),async n=>{const e=n.req.valid("json"),{client_id:t,username:i}=e;n.set("username",i);const r=await n.env.data.clients.get(t);if(!r)throw new j(400,{message:"Client not found"});n.set("client_id",t),n.set("tenant_id",r.tenant.id);const s=i.toLocaleLowerCase();let a;if("otp"in e){const p=await n.env.data.codes.get(r.tenant.id,e.otp,"otp");if(!p)throw wd();const g=await n.env.data.logins.get(r.tenant.id,p.login_id);if(!g||g.authParams.username!==s)throw wd();a=g}else if("password"in e)await Cv(n,r,{username:i,password:e.password,client_id:t}),a=await n.env.data.logins.create(r.tenant.id,{expires_at:new Date(Date.now()+bd).toISOString(),authParams:{client_id:r.id,username:s},...Hn(n.req)});else throw new j(400,{message:"Code or password required"});const c=jv(),l=Me(12),u=await n.env.data.codes.create(r.tenant.id,{code_id:Me(),code_type:"ticket",login_id:a.login_id,expires_at:new Date(Date.now()+bd).toISOString(),code_verifier:[l,c].join("|")});return n.json({login_ticket:u.code_id,co_verifier:c,co_id:l})});function Ov(n,e){var i,r,s;if(!n||e.length===0)return!1;const t=((i=vo(n))==null?void 0:i.host)??null;if(!t)return!1;for(const a of e){let c;if(a.startsWith("http://")||a.startsWith("https://")?c=((r=vo(a))==null?void 0:r.host)??null:c=((s=vo("https://"+a))==null?void 0:s.host)??null,t===c)return!0}return!1}function vo(n){try{return new URL(n)}catch{return null}}async function Bv({ctx:n,session:e,client:t,authParams:i,connection:r,login_hint:s}){const a=await n.env.data.logins.create(t.tenant.id,{expires_at:new Date(Date.now()+es*1e3).toISOString(),authParams:i,...Hn(n.req)});if(e&&s){const c=await n.env.data.users.get(t.tenant.id,e.user_id);if((c==null?void 0:c.email)===s)return ei(n,{client:t,loginSession:a,authParams:i,user:c,sessionId:e.id})}if(r==="email"&&s){const c=hh();return await n.env.data.codes.create(t.tenant.id,{code_id:c,code_type:"otp",login_id:a.login_id,expires_at:new Date(Date.now()+es*1e3).toISOString()}),await ph(n,s,c),n.redirect(`/u/enter-code?state=${a.login_id}`)}return e?n.redirect(`/u/check-account?state=${a.login_id}`):n.redirect(`/u/enter-email?state=${a.login_id}`)}function Tv(n){if(n==="Username-Password-Authentication")return"auth2";if(n==="email")return"email";throw new j(403,{message:"Invalid realm"})}async function Rv(n,e,t,i,r){var _;const{env:s}=n;n.set("connection",r);const a=await s.data.codes.get(e,t,"ticket");if(!a||a.used_at)throw new j(403,{message:"Ticket not found"});const c=await s.data.logins.get(e,a.login_id);if(!c||!c.authParams.username)throw new j(403,{message:"Session not found"});const l=await s.data.clients.get(c.authParams.client_id);if(!l)throw new j(403,{message:"Client not found"});n.set("client_id",c.authParams.client_id),await s.data.codes.used(e,t);const u=Tv(r);let p=await as({userAdapter:s.data.users,tenant_id:e,email:c.authParams.username,provider:u});p||(p=await s.data.users.create(e,{user_id:`email|${Ya()}`,email:c.authParams.username,name:c.authParams.username,provider:"email",connection:"email",email_verified:!0,is_social:!1,last_ip:"",last_login:new Date().toISOString()})),n.set("username",p.email),n.set("user_id",p.user_id);const g=await ch(n,{user:p,client:l,scope:i.scope,audience:i.audience});return ei(n,{authParams:{scope:(_=c.authParams)==null?void 0:_.scope,...i},loginSession:c,sessionId:g.id,user:p,client:l})}async function kd(n,e){return`<!DOCTYPE html>
|
|
149
|
+
</html>`;return new Response(r,{headers:{"Content-Type":"text/html"}})}async function nv(n,e,t,i,r){var _,x,h;if(!t.redirect_uri)throw new j(400,{message:"Missing redirect_uri in authParams"});const[s]=await n.env.data.keys.list();if(!s)throw new j(500,{message:"No signing key found"});if(!((_=e.addons)!=null&&_.samlp))throw new j(400,{message:`SAML Addon is not enabled for client ${e.id}`});const{recipient:a,audience:c}=e.addons.samlp,l=t.state||"";if(!a||!l||!i||!t.state)throw new j(400,{message:"Missing recipient or inResponseTo"});const u=JSON.parse(t.state),p=new URL(t.redirect_uri),g=await iv(n,{issuer:n.env.ISSUER,audience:c||t.client_id,destination:p.toString(),inResponseTo:u.requestId,userId:((h=(x=i.app_metadata)==null?void 0:x.vimeo)==null?void 0:h.user_id)||i.user_id,email:i.email,sessionIndex:r,signature:{privateKeyPem:s.pkcs7,cert:s.cert,kid:s.kid}});return tv(p.toString(),g,u.relayState)}async function iv(n,e){const t=e.notBefore||new Date().toISOString(),i=e.notAfter||new Date(new Date(t).getTime()+10*60*1e3).toISOString(),r=e.issueInstant||t,s=e.sessionNotOnOrAfter||i,a=e.responseId||`_${Me()}`,c=e.assertionId||`_${Me()}`,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":i,"@_Recipient":e.destination}}],":@":{"@_Method":"urn:oasis:names:tc:SAML:2.0:cm:bearer"}}]},{"saml:Conditions":[{"saml:AudienceRestriction":[{"saml:Audience":[{"#text":e.audience}]}]}],":@":{"@_NotBefore":t,"@_NotOnOrAfter":i}},{"saml:AuthnStatement":[{"saml:AuthnContext":[{"saml:AuthnContextClassRef":[{"#text":"urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified"}]}]}],":@":{"@_AuthnInstant":r,"@_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":r,"@_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":r,"@_Version":"2.0"}}];let p=new ev.XMLBuilder({ignoreAttributes:!1,suppressEmptyNode:!0,preserveOrder:!0}).build(l);if(e.signature){const _=await fetch(n.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(!_.ok)throw new Error(`Failed to sign SAML response: ${_.status}`);p=await _.text()}return e.encode===!1?p:btoa(p)}const gd=["sub","iss","aud","exp","nbf","iat","jti"];async function Yc(n,e){var m,b;const{authParams:t,user:i,client:r,session_id:s}=e,c=(await n.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 j(500,{message:"No signing key available"});const u=Om(l.pkcs7),p={aud:t.audience||"default",scope:t.scope||"",sub:(i==null?void 0:i.user_id)||t.client_id,iss:n.env.ISSUER,tenant_id:n.var.tenant_id,sid:s},g=i&&((m=t.scope)!=null&&m.split(" ").includes("openid"))?{aud:t.client_id,sub:i.user_id,iss:n.env.ISSUER,sid:s,nonce:t.nonce,given_name:i.given_name,family_name:i.family_name,nickname:i.nickname,picture:i.picture,locale:i.locale,name:i.name,email:i.email,email_verified:i.email_verified}:void 0;(b=n.env.hooks)!=null&&b.onExecuteCredentialsExchange&&await n.env.hooks.onExecuteCredentialsExchange({client:r,user:i,scope:t.scope||"",grant_type:""},{accessToken:{setCustomClaim:(S,O)=>{if(gd.includes(S))throw new Error(`Cannot overwrite reserved claim '${S}'`);p[S]=O}},idToken:{setCustomClaim:(S,O)=>{if(gd.includes(S))throw new Error(`Cannot overwrite reserved claim '${S}'`);g&&(g[S]=O)}},access:{deny:S=>{throw new j(400,{message:`Access denied: ${S}`})}}});const _={includeIssuedTimestamp:!0,expiresIn:new qc(1,"d"),headers:{kid:l.kid}},x=await ld("RS256",u,p,_),h=g?await ld("RS256",u,g,_):void 0;return{access_token:x,refresh_token:e.refresh_token,id_token:h,token_type:"Bearer",expires_in:86400}}async function rv(n,e){const{client:t,scope:i,audience:r=t.tenant.audience,session_id:s}=e;return await n.env.data.refreshTokens.create(t.tenant.id,{id:Me(),session_id:s,client_id:t.id,expires_at:new Date(Date.now()+Hc*1e3).toISOString(),user_id:e.user.user_id,device:{last_ip:"",initial_ip:"",last_user_agent:"",initial_user_agent:"",initial_asn:"",last_asn:""},resource_servers:[{audience:r,scopes:i}],rotating:!1})}async function ch(n,e){const{user:t,client:i,scope:r,audience:s}=e,a=await n.env.data.sessions.create(i.tenant.id,{id:Me(),user_id:t.user_id,expires_at:new Date(Date.now()+Hc*1e3).toISOString(),used_at:new Date().toISOString(),device:{last_ip:n.req.header("x-real-ip")||"",initial_ip:n.req.header("x-real-ip")||"",last_user_agent:n.req.header("user-agent")||"",initial_user_agent:n.req.header("user-agent")||"",initial_asn:"",last_asn:""},clients:[i.id]}),c=r!=null&&r.split(" ").includes("offline_access")?await rv(n,{...e,session_id:a.id,scope:r,audience:s}):void 0;return{...a,refresh_token:c}}async function ei(n,e){var g;const{authParams:t,user:i,client:r}=e,s=be(n,{type:_e.SUCCESS_LOGIN,description:`Successful login for ${i.user_id}`,userId:i.user_id});_t(n,n.env.data.logs.create(r.tenant.id,s)),_t(n,n.env.data.users.update(r.tenant.id,i.user_id,{last_login:new Date().toISOString(),last_ip:n.req.header("x-real-ip")||"",login_count:i.login_count+1}));let a=e.refreshToken,c=e.sessionId;if(!c){const _=await ch(n,{user:i,client:r,scope:t.scope,audience:t.audience});c=_.id,a=(g=_.refresh_token)==null?void 0:g.id}if(e.authParams.response_mode===Vt.SAML_POST)return nv(n,e.client,e.authParams,i,c);const l=await Yc(n,{authParams:t,user:i,client:r,session_id:c,refresh_token:a}),u=new Headers({"set-cookie":eh(r.tenant.id,c)});if(t.response_mode===Vt.WEB_MESSAGE)return n.json(l,{headers:u});if((t.response_type||Ut.CODE)===Ut.CODE){if(!e.loginSession)throw new j(500,{message:"Login session not found"});const _=await n.env.data.codes.create(r.tenant.id,{code_id:Me(),user_id:i.user_id,code_type:"authorization_code",login_id:e.loginSession.login_id,expires_at:new Date(Date.now()+F0*1e3).toISOString()});u.set("location",`${t.redirect_uri}?state=${e.authParams.state}&code=${_.code_id}`)}return new Response("Redirecting",{status:302,headers:u})}function sv(n){return async(e,t)=>{if(!t.email||!t.email_verified)return n.users.create(e,t);const i=await Kd({userAdapter:n.users,tenant_id:e,email:t.email});return i?(await n.users.create(e,{...t,linked_to:i.user_id}),i):n.users.create(e,t)}}async function lh(n,e,t){for await(const i of e)if(!(await fetch(i.url,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})).ok){const s=be(n,{type:_e.FAILED_LOGIN_INCORRECT_PASSWORD,description:"Invalid password"});await t.logs.create(n.var.tenant_id,s)}}function ov(n,e){return async(t,i)=>{const{hooks:r}=await e.hooks.list(t);return await lh(n,r,{tenant_id:t,user:i,trigger_id:"post-user-registration"}),i}}function av(n,e){return async(t,i)=>{const{hooks:r}=await e.hooks.list(t,{q:"trigger_id:pre-user-signup",page:0,per_page:100,include_totals:!1});await lh(n,r,{tenant_id:t,email:i,trigger_id:"pre-user-signup"})}}function cv(n,e){return async(t,i)=>{let r=await sv(e)(t,i);return await ov(n,e)(t,r),r}}async function lv(n,e,t,i){if(e.disable_sign_ups&&!await Kd({userAdapter:n.env.data.users,tenant_id:e.tenant.id,email:i})){const s=be(n,{type:_e.FAILED_SIGNUP,description:"Public signup is disabled"});throw await n.env.data.logs.create(e.tenant.id,s),new j(400,{message:"Signups are disabled for this client"})}await av(n,t)(n.var.tenant_id||"",i)}function uv(n,e){return{...e,users:{...e.users,create:cv(n,e)}}}async function dv(n,e,t,i){if(!i.state)throw new j(400,{message:"State not found"});const r=e.connections.find(l=>l.name===t);if(!r){n.set("client_id",e.id);const l=be(n,{type:_e.FAILED_LOGIN,description:"Connection not found"});throw await n.env.data.logs.create(e.tenant.id,l),new j(403,{message:"Connection Not Found"})}let s=await n.env.data.logins.get(e.tenant.id,i.state);s||(s=await n.env.data.logins.create(e.tenant.id,{expires_at:new Date(Date.now()+es*1e3).toISOString(),authParams:i,...Hn(n.req)}));const c=await Yf(n,r.strategy).getRedirect(n,r);return await n.env.data.codes.create(e.tenant.id,{login_id:s.login_id,code_id:c.code,code_type:"oauth2_state",connection_id:r.id,code_verifier:c.codeVerifier,expires_at:new Date(Date.now()+K0*1e3).toISOString()}),n.redirect(c.redirectUrl)}async function _d(n,{code:e,state:t}){var h;const{env:i}=n,r=await i.data.codes.get(n.var.tenant_id||"",t,"oauth2_state");if(!r||!r.connection_id)throw new j(403,{message:"State not found"});const s=await i.data.logins.get(n.var.tenant_id||"",r.login_id);if(!s)throw new j(403,{message:"Session not found"});const a=await Kc(i,s.authParams.client_id);n.set("client_id",a.id),n.set("tenant_id",a.tenant.id);const c=a.connections.find(m=>m.id===r.connection_id);if(!c){const m=be(n,{type:_e.FAILED_LOGIN,description:"Connection not found"});throw await i.data.logs.create(a.tenant.id,m),new j(403,{message:"Connection not found"})}if(n.set("connection",c.name),!s.authParams.redirect_uri){const m=be(n,{type:_e.FAILED_LOGIN,description:"Redirect URI not defined"});throw await i.data.logs.create(a.tenant.id,m),new j(403,{message:"Redirect URI not defined"})}if(!Xs(s.authParams.redirect_uri,a.callbacks||[],{allowPathWildcards:!0})){const m=`Invalid redirect URI - ${s.authParams.redirect_uri}`,b=be(n,{type:_e.FAILED_LOGIN,description:m});throw await i.data.logs.create(a.tenant.id,b),new j(403,{message:m})}const u=await Yf(n,c.strategy).validateAuthorizationCodeAndGetUser(n,c,e,r.code_verifier),{sub:p,...g}=u;n.set("user_id",p);const _=((h=u.email)==null?void 0:h.toLocaleLowerCase())||`${c.name}.${p}@${new URL(n.env.ISSUER).hostname}`;n.set("username",_);let x=await as({userAdapter:i.data.users,tenant_id:a.tenant.id,email:_,provider:c.name});if(!x){try{await lv(n,a,n.env.data,_)}catch(m){const b=m;throw new j(500,{message:`Failed to run preUserSignupHook: ${b.message}`})}x=await i.data.users.create(a.tenant.id,{user_id:`${c.name}|${p}`,email:_,name:_,provider:c.name,connection:c.name,email_verified:!0,last_ip:"",is_social:!0,last_login:new Date().toISOString(),profileData:JSON.stringify(g)}),n.set("user_id",x.user_id)}return ei(n,{client:a,authParams:s.authParams,loginSession:s,user:x})}async function md(n,e,t,i,r,s){const a=await n.env.data.codes.get(n.var.tenant_id||"",e,"oauth2_state");if(!a)throw new j(400,{message:"State not found"});const c=await n.env.data.logins.get(n.var.tenant_id,a.login_id);if(!c)throw new j(400,{message:"Login not found"});const{redirect_uri:l}=c.authParams;if(!l)throw new j(400,{message:"Redirect uri not found"});const u=be(n,{type:_e.FAILED_LOGIN,description:`Failed connection login: ${r} ${t}, ${i}`});_t(n,n.env.data.logs.create(n.var.tenant_id,u));const p=new URL(l);return D0(p,{error:t,error_description:i,error_reason:s,error_code:r,state:c.authParams.state}),n.redirect(`${vt(n.env)}enter-email?state=${c.login_id}&error=${t}`)}const pv=new o.OpenAPIHono().openapi(o.createRoute({tags:["oauth2"],method:"get",path:"/",request:{query:o.z.object({state:o.z.string(),code:o.z.string().optional(),scope:o.z.string().optional(),hd:o.z.string().optional(),error:o.z.string().optional(),error_description:o.z.string().optional(),error_code:o.z.string().optional(),error_reason:o.z.string().optional()})},responses:{302:{description:"Redirect to the client's redirect uri"}}}),async n=>{const{state:e,code:t,error:i,error_description:r,error_code:s,error_reason:a}=n.req.valid("query");if(i)return md(n,e,i,r,s,a);if(!t)throw new j(400,{message:"Code is required"});return _d(n,{code:t,state:e})}).openapi(o.createRoute({tags:["oauth2"],method:"post",path:"/",request:{body:{content:{"application/x-www-form-urlencoded":{schema:o.z.object({state:o.z.string(),code:o.z.string().optional(),scope:o.z.string().optional(),hd:o.z.string().optional(),error:o.z.string().optional(),error_description:o.z.string().optional(),error_code:o.z.string().optional(),error_reason:o.z.string().optional()})}}}},responses:{302:{description:"Redirect to the client's redirect uri"}}}),async n=>{const{state:e,code:t,error:i,error_description:r,error_code:s,error_reason:a}=n.req.valid("form");if(i)return md(n,e,i,r,s,a);if(!t)throw new j(400,{message:"Code is required"});return _d(n,{code:t,state:e})}),fv=new o.OpenAPIHono().openapi(o.createRoute({tags:["oauth2"],method:"get",path:"/",request:{query:o.z.object({client_id:o.z.string(),returnTo:o.z.string().optional()}),header:o.z.object({cookie:o.z.string().optional()})},responses:{302:{description:"Log the user out"}}}),async n=>{const{client_id:e,returnTo:t}=n.req.valid("query"),i=await n.env.data.clients.get(e);if(!i)return n.text("OK");const r=await n.env.data.clients.get("DEFAULT_CLIENT");n.set("client_id",e),n.set("tenant_id",i.tenant.id);const s=t||n.req.header("referer");if(!s)return n.text("OK");if(!Xs(s,[...i.allowed_logout_urls||[],...(r==null?void 0:r.allowed_logout_urls)||[]],{allowPathWildcards:!0}))throw new j(400,{message:"Invalid redirect uri"});const a=n.req.header("cookie");if(a){const l=Qf(i.tenant.id,a);if(l){const u=await n.env.data.sessions.get(i.tenant.id,l);if(u){const p=await n.env.data.users.get(i.tenant.id,u.user_id);p&&(n.set("user_id",p.user_id),n.set("connection",p.connection))}await n.env.data.sessions.remove(i.tenant.id,l)}}const c=be(n,{type:_e.SUCCESS_LOGOUT,description:"User successfully logged out"});return await n.env.data.logs.create(i.tenant.id,c),new Response("Redirecting",{status:302,headers:{"set-cookie":Rm(i.tenant.id),location:s}})}),yd=o.z.object({sub:o.z.string(),email:o.z.string().optional(),family_name:o.z.string().optional(),given_name:o.z.string().optional(),email_verified:o.z.boolean()}),hv=new o.OpenAPIHono().openapi(o.createRoute({tags:["oauth2"],method:"get",path:"/",request:{},security:[{Bearer:["openid"]}],responses:{200:{content:{"application/json":{schema:yd}},description:"Userinfo"}}}),async n=>{if(!n.var.user)throw new j(404,{message:"User not found"});const e=await n.env.data.users.get(n.var.user.tenant_id,n.var.user.sub);if(!e)throw new j(404,{message:"User not found"});return n.json(yd.parse({...e,sub:e.user_id}))}),gv=new o.OpenAPIHono().openapi(o.createRoute({tags:["well known"],method:"get",path:"/jwks.json",request:{},responses:{200:{content:{"application/json":{schema:jd}},description:"List of tenants"}}}),async n=>{const e=await n.env.data.keys.list(),t=await Promise.all(e.map(async i=>{const s=await new Mc(i.cert).publicKey.export(),a=await crypto.subtle.exportKey("jwk",s);return Ga.parse({...a,kid:i.kid})}));return n.json({keys:t},{headers:{"access-control-allow-origin":"*","access-control-allow-method":"GET","cache-control":`public, max-age=${er}, stale-while-revalidate=${er*2}, stale-if-error=86400`}})}).openapi(o.createRoute({tags:["well known"],method:"get",path:"/openid-configuration",request:{},responses:{200:{content:{"application/json":{schema:ko}},description:"List of tenants"}}}),async n=>{const e=ko.parse({issuer:vm(n.env),authorization_endpoint:`${Ie(n.env)}authorize`,token_endpoint:`${Ie(n.env)}oauth/token`,device_authorization_endpoint:`${Ie(n.env)}oauth/device/code`,userinfo_endpoint:`${Ie(n.env)}userinfo`,mfa_challenge_endpoint:`${Ie(n.env)}mfa/challenge`,jwks_uri:`${Ie(n.env)}.well-known/jwks.json`,registration_endpoint:`${Ie(n.env)}oidc/register`,revocation_endpoint:`${Ie(n.env)}oauth/revoke`,scopes_supported:["openid","profile","offline_access","name","given_name","family_name","nickname","email","email_verified","picture","created_at","identities","phone","address"],response_types_supported:["code","token","id_token","code token","code id_token","token id_token","code token id_token"],code_challenge_methods_supported:["S256","plain"],response_modes_supported:["query","fragment","form_post"],subject_types_supported:["public"],id_token_signing_alg_values_supported:["RS256"],token_endpoint_auth_methods_supported:["client_secret_basic","client_secret_post"],claims_supported:["aud","auth_time","created_at","email","email_verified","exp","family_name","given_name","iat","identities","iss","name","nickname","phone_number","picture","sub"],request_uri_parameter_supported:!1,request_parameter_supported:!1,token_endpoint_auth_signing_alg_values_supported:["RS256","RS384","PS256"]});return n.json(e,{headers:{"access-control-allow-origin":"*","access-control-allow-method":"GET","cache-control":`public, max-age=${er}, stale-while-revalidate=${er*2}, stale-if-error=86400`}})});function cr(n,e){if(!n||!e||n.length!==e.length)return!1;let t=0;for(let i=0;i<n.length;i++)t|=n.charCodeAt(i)^e.charCodeAt(i);return t===0}const uh=o.z.object({grant_type:o.z.literal("client_credentials"),scope:o.z.string().optional(),client_secret:o.z.string(),client_id:o.z.string(),audience:o.z.string().optional()});async function _v(n,e){const t=await n.env.data.clients.get(e.client_id);if(!t)throw new j(403,{message:"Invalid client credentials"});if(t.client_secret&&!cr(t.client_secret,e.client_secret))throw new j(403,{message:"Invalid client credentials"});const i={client_id:t.id,scope:e.scope,audience:e.audience},r=await Yc(n,{authParams:i,client:t});return n.json(r)}const mv=o.z.object({grant_type:o.z.literal("authorization_code"),client_id:o.z.string(),code:o.z.string(),redirect_uri:o.z.string().optional(),client_secret:o.z.string().optional(),code_verifier:o.z.string().optional()}).refine(n=>"client_secret"in n&&!("code_verifier"in n)||!("client_secret"in n)&&"code_verifier"in n,{message:"Must provide either client_secret (standard flow) or code_verifier/code_verifier_mode (PKCE flow), but not both"});async function yv(n,e){const t=await n.env.data.clients.get(e.client_id);if(!t)throw new j(403,{message:"Client not found"});const i=await n.env.data.codes.get(t.tenant.id,e.code,"authorization_code");if(!i||!i.user_id)throw new j(403,{message:"Invalid client credentials"});if(new Date(i.expires_at)<new Date)throw new j(403,{message:"Code expired"});if(i.used_at)throw new j(403,{message:"Code already used"});const r=await n.env.data.logins.get(t.tenant.id,i.login_id);if(!r)throw new j(403,{message:"Invalid login"});if("client_secret"in e){const a=await n.env.data.clients.get("DEFAULT_CLIENT");if(!cr(t.client_secret,e.client_secret)&&!cr(a==null?void 0:a.client_secret,e.client_secret))throw new j(403,{message:"Invalid client credentials"})}else if("code_verifier"in e&&typeof e.code_verifier=="string"&&"code_challenge_method"in r.authParams&&typeof r.authParams.code_challenge_method=="string"){const a=await Bm(e.code_verifier,r.authParams.code_challenge_method);if(!cr(a,r.authParams.code_challenge||""))throw new j(403,{message:"Invalid client credentials"})}if(r.authParams.redirect_uri&&r.authParams.redirect_uri!==e.redirect_uri)throw new j(403,{message:"Invalid redirect uri"});const s=await n.env.data.users.get(t.tenant.id,i.user_id);if(!s)throw new j(403,{message:"User not found"});return await n.env.data.codes.used(t.tenant.id,e.code),ei(n,{user:s,client:t,loginSession:r,authParams:{...r.authParams,response_mode:Vt.WEB_MESSAGE}})}const vv=o.z.object({grant_type:o.z.literal("refresh_token"),client_id:o.z.string(),redirect_uri:o.z.string().optional(),refresh_token:o.z.string()});async function wv(n,e){const t=await n.env.data.clients.get(e.client_id);if(!t)throw new j(403,{message:"Client not found"});const i=await n.env.data.refreshTokens.get(t.tenant.id,e.refresh_token);if(i){if(i.expires_at&&new Date(i.expires_at)<new Date||i.idle_expires_at&&new Date(i.idle_expires_at)<new Date)throw new j(403,{message:JSON.stringify({error:"invalid_grant",error_description:"Refresh token has expired"})})}else throw new j(403,{message:JSON.stringify({error:"invalid_grant",error_description:"Invalid refresh token"})});const r=await n.env.data.users.get(t.tenant.id,i.user_id);if(!r)throw new j(403,{message:"User not found"});const s=i.resource_servers[0];if(i.idle_expires_at){const a=new Date(Date.now()+2592e6);await n.env.data.refreshTokens.update(t.tenant.id,i.id,{idle_expires_at:a.toISOString(),last_exchanged_at:new Date().toISOString(),device:{...i.device,last_ip:n.req.header["x-real-ip"]||"",last_user_agent:n.req.header["user-agent"]||""}})}return ei(n,{user:r,client:t,refreshToken:i.id,sessionId:i.session_id,authParams:{client_id:t.id,audience:s==null?void 0:s.audience,scope:s==null?void 0:s.scopes,response_mode:Vt.WEB_MESSAGE}})}const vd=o.z.object({client_id:o.z.string().optional(),client_secret:o.z.string().optional()}),bv=o.z.union([uh.extend(vd.shape),o.z.object({grant_type:o.z.literal("authorization_code"),client_id:o.z.string(),code:o.z.string(),redirect_uri:o.z.string(),code_verifier:o.z.string().min(43).max(128)}),o.z.object({grant_type:o.z.literal("authorization_code"),code:o.z.string(),redirect_uri:o.z.string().optional(),...vd.shape}),o.z.object({grant_type:o.z.literal("refresh_token"),client_id:o.z.string(),refresh_token:o.z.string(),redirect_uri:o.z.string().optional()})]);function kv(n){if(!n)return{};const[e,t]=n.split(" ");if((e==null?void 0:e.toLowerCase())==="basic"&&t){const[i,r]=atob(t).split(":");return{client_id:i,client_secret:r}}return{}}const xv=new o.OpenAPIHono().openapi(o.createRoute({tags:["oauth2"],method:"post",path:"/",request:{body:{content:{"application/x-www-form-urlencoded":{schema:bv}}}},responses:{200:{content:{"application/json":{schema:Pd}},description:"Tokens"}}}),async n=>{const e=n.req.valid("form"),t=kv(n.req.header("Authorization")),i={...e,...t};if(!i.client_id)throw new j(400,{message:"client_id is required"});switch(e.grant_type){case ci.AuthorizationCode:return yv(n,mv.parse(i));case ci.ClientCredential:return _v(n,uh.parse(i));case ci.RefreshToken:return wv(n,vv.parse(i));default:throw new j(400,{message:"Not implemented"})}});var Xc={exports:{}};const Qc=[{id:0,value:"Too weak",minDiversity:0,minLength:0},{id:1,value:"Weak",minDiversity:2,minLength:6},{id:2,value:"Medium",minDiversity:4,minLength:8},{id:3,value:"Strong",minDiversity:4,minLength:10}],dh=(n,e=Qc,t="!\"#$%&'()*+,-./:;<=>?@[\\\\\\]^_`{|}~")=>{let i=n||"";e[0].minDiversity=0,e[0].minLength=0;const r=[{regex:"[a-z]",message:"lowercase"},{regex:"[A-Z]",message:"uppercase"},{regex:"[0-9]",message:"number"}];t&&r.push({regex:`[${t}]`,message:"symbol"});let s={};s.contains=r.filter(c=>new RegExp(`${c.regex}`).test(i)).map(c=>c.message),s.length=i.length;let a=e.filter(c=>s.contains.length>=c.minDiversity).filter(c=>s.length>=c.minLength).sort((c,l)=>l.id-c.id).map(c=>({id:c.id,value:c.value}));return Object.assign(s,a[0]),s};Xc.exports={passwordStrength:dh,defaultOptions:Qc};var Sv=Xc.exports.passwordStrength=dh;Xc.exports.defaultOptions=Qc;function Av(n){return Sv(n).id<2?!1:n.length>=8&&/[a-z]/.test(n)&&/[A-Z]/.test(n)&&/[0-9]/.test(n)&&/[^A-Za-z0-9]/.test(n)}async function eo(n,e){var r;const t=await n.env.data.emailProviders.get(n.var.tenant_id)||(n.env.DEFAULT_TENANT_ID?await n.env.data.emailProviders.get(n.env.DEFAULT_TENANT_ID):null);if(!t)throw new j(500,{message:"Email provider not found"});const i=(r=n.env.emailProviders)==null?void 0:r[t.name];if(!i)throw new j(500,{message:"Email provider not found"});await i({emailProvider:t,...e,from:t.default_from_address||`login@${n.env.ISSUER}`})}async function Iv(n,e,t,i){const r=await n.env.data.tenants.get(n.var.tenant_id);if(!r)throw new j(500,{message:"Tenant not found"});const s=`${vt(n.env)}reset-password?state=${i}&code=${t}`,a={vendorName:r.name,lng:r.language||"en"};await eo(n,{to:e,subject:"Reset your password",html:`Click here to reset your password: ${vt(n.env)}reset-password?state=${i}&code=${t}`,template:"auth-password-reset",data:{vendorName:r.name,logo:r.logo||"",passwordResetUrl:s,supportUrl:r.support_url||"https://support.sesamy.com",buttonColor:r.primary_color||"#7d68f4",passwordResetTitle:ue("password_reset_title",a),resetPasswordEmailClickToReset:ue("reset_password_email_click_to_reset",a),resetPasswordEmailReset:ue("reset_password_email_reset",a),supportInfo:ue("support_info",a),contactUs:ue("contact_us",a),copyright:ue("copyright",a)}})}async function Ev(n,e,t){const i=await n.env.data.tenants.get(n.var.tenant_id);if(!i)throw new j(500,{message:"Tenant not found"});const r={vendorName:i.name,code:t,lng:i.language||"en"};await eo(n,{to:e,subject:ue("code_email_subject",r),html:`Click here to validate your email: ${vt(n.env)}validate-email`,template:"auth-link",data:{code:t,vendorName:i.name,logo:i.logo||"",supportUrl:i.support_url||"",magicLink:`${Ie(n.env)}passwordless/verify_redirect?ticket=${t}`,buttonColor:i.primary_color||"",welcomeToYourAccount:ue("welcome_to_your_account",r),linkEmailClickToLogin:ue("link_email_click_to_login",r),linkEmailLogin:ue("link_email_login",r),linkEmailOrEnterCode:ue("link_email_or_enter_code",r),codeValid30Mins:ue("code_valid_30_minutes",r),supportInfo:ue("support_info",r),contactUs:ue("contact_us",r),copyright:ue("copyright",r)}});const s=be(n,{type:_e.CODE_LINK_SENT,description:e});_t(n,n.env.data.logs.create(i.id,s))}async function ph(n,e,t){const i=await n.env.data.tenants.get(n.var.tenant_id);if(!i)throw new j(500,{message:"Tenant not found"});const r={vendorName:i.name,code:t,lng:i.language||"en"};await eo(n,{to:e,subject:ue("code_email_subject",r),html:`Click here to validate your email: ${vt(n.env)}validate-email`,template:"auth-link",data:{code:t,vendorName:i.name,logo:i.logo||"",supportUrl:i.support_url||"",magicLink:`${Ie(n.env)}passwordless/verify_redirect?ticket=${t}`,buttonColor:i.primary_color||"",welcomeToYourAccount:ue("welcome_to_your_account",r),linkEmailClickToLogin:ue("link_email_click_to_login",r),linkEmailLogin:ue("link_email_login",r),linkEmailOrEnterCode:ue("link_email_or_enter_code",r),codeValid30Mins:ue("code_valid_30_minutes",r),supportInfo:ue("support_info",r),contactUs:ue("contact_us",r),copyright:ue("copyright",r)}});const s=be(n,{type:_e.CODE_LINK_SENT,description:e});_t(n,n.env.data.logs.create(i.id,s))}async function fh(n,e){const t=await n.env.data.tenants.get(n.var.tenant_id);if(!t)throw new j(500,{message:"Tenant not found"});const i={vendorName:t.name,lng:t.language||"en"};await eo(n,{to:e.email,subject:"Validate your email address",html:`Click here to validate your email: ${vt(n.env)}validate-email`,template:"auth-verify-email",data:{vendorName:t.name,logo:t.logo||"",emailValidationUrl:`${vt(n.env)}validate-email`,supportUrl:t.support_url||"https://support.sesamy.com",buttonColor:t.primary_color||"#7d68f4",welcomeToYourAccount:ue("welcome_to_your_account",i),verifyEmailVerify:ue("verify_email_verify",i),supportInfo:ue("support_info",i),contactUs:ue("contact_us",i),copyright:ue("copyright",i)}})}const zv=new o.OpenAPIHono().openapi(o.createRoute({tags:["dbconnections"],method:"post",path:"/signup",request:{body:{content:{"application/json":{schema:o.z.object({client_id:o.z.string(),connection:o.z.literal("Username-Password-Authentication"),email:o.z.string().transform(n=>n.toLowerCase()),password:o.z.string()})}}}},responses:{200:{content:{"application/json":{schema:o.z.object({_id:o.z.string(),email:o.z.string(),email_verified:o.z.boolean(),app_metadata:o.z.object({}),user_metadata:o.z.object({})})}},description:"Created user"}}}),async n=>{const{email:e,password:t,client_id:i}=n.req.valid("json"),r=await n.env.data.clients.get(i);if(!r)throw new j(400,{message:"Client not found"});if(n.set("client_id",r.id),n.set("tenant_id",r.tenant.id),!Av(t))throw new j(400,{message:"Password does not meet the requirements"});if(await as({userAdapter:n.env.data.users,tenant_id:r.tenant.id,email:e,provider:"auth2"}))throw new j(400,{message:"Invalid sign up"});const a=await n.env.data.users.create(r.tenant.id,{user_id:`auth2|${Ya()}`,email:e,email_verified:!1,provider:"auth2",connection:"Username-Password-Authentication",is_social:!1});n.set("user_id",a.user_id),n.set("username",a.email),n.set("connection",a.connection);const c=await Za.hash(t,10);await n.env.data.passwords.create(r.tenant.id,{user_id:a.user_id,password:c,algorithm:"bcrypt"}),await fh(n,a);const l=be(n,{type:_e.SUCCESS_SIGNUP,description:"Successful signup"});return await n.env.data.logs.create(r.tenant.id,l),n.json({_id:a.user_id,email:a.email,email_verified:!1,app_metadata:{},user_metadata:{}})}).openapi(o.createRoute({tags:["dbconnections"],method:"post",path:"/change_password",request:{body:{content:{"application/json":{schema:o.z.object({client_id:o.z.string(),connection:o.z.literal("Username-Password-Authentication"),email:o.z.string().transform(n=>n.toLowerCase())})}}}},responses:{200:{description:"Redirect to the client's redirect uri"}}}),async n=>{const{email:e,client_id:t}=n.req.valid("json"),i=await n.env.data.clients.get(t);if(!i)throw new j(400,{message:"Client not found"});if(n.set("client_id",i.id),n.set("tenant_id",i.tenant.id),!await Xa({userAdapter:n.env.data.users,tenant_id:i.tenant.id,email:e,provider:"auth2"}))return n.html("If an account with that email exists, we've sent instructions to reset your password.");const s={client_id:t,username:e},a=await n.env.data.logins.create(i.tenant.id,{expires_at:new Date(Date.now()+es*1e3).toISOString(),authParams:s,...Hn(n.req)});return await Iv(n,e,a.login_id,a.authParams.state),n.html("If an account with that email exists, we've sent instructions to reset your password.")});function hh(){const n="1234567890";let e="";for(let t=0;t<6;t+=1)e+=n[Math.floor(Math.random()*10)];return e.toString()}const $v=new o.OpenAPIHono().openapi(o.createRoute({tags:["passwordless"],method:"post",path:"/start",request:{body:{content:{"application/json":{schema:o.z.object({client_id:o.z.string(),connection:o.z.string(),email:o.z.string().transform(n=>n.toLowerCase()),send:o.z.enum(["link","code"]),authParams:Wa.omit({client_id:!0})})}}}},responses:{200:{description:"Status"}}}),async n=>{const e=n.req.valid("json"),{env:t}=n,{client_id:i,email:r,send:s,authParams:a}=e,c=await n.env.data.clients.get(i);if(!c)throw new j(400,{message:"Client not found"});n.set("client_id",c.id),n.set("tenant_id",c.tenant.id);const l=await t.data.logins.create(c.tenant.id,{authParams:{...a,client_id:i,username:r},expires_at:new Date(Date.now()+ed).toISOString(),...Hn(n.req)}),u=await t.data.codes.create(c.tenant.id,{code_id:hh(),code_type:"otp",login_id:l.login_id,expires_at:new Date(Date.now()+ed).toISOString()});return s==="link"?await ph(n,r,u.code_id):await Ev(n,r,u.code_id),n.html("OK")}).openapi(o.createRoute({tags:["passwordless"],method:"get",path:"/verify_redirect",request:{query:o.z.object({scope:o.z.string(),response_type:o.z.nativeEnum(Ut),redirect_uri:o.z.string(),state:o.z.string(),nonce:o.z.string().optional(),verification_code:o.z.string(),connection:o.z.string(),client_id:o.z.string(),email:o.z.string().transform(n=>n.toLowerCase()),audience:o.z.string().optional()})},responses:{302:{description:"Status"}}}),async n=>{const{env:e}=n,{client_id:t,email:i,verification_code:r,redirect_uri:s,state:a,scope:c,audience:l,response_type:u,nonce:p}=n.req.valid("query"),g=await Kc(e,t);n.set("client_id",g.id),n.set("tenant_id",g.tenant.id),n.set("connection","email");const _=await e.data.codes.get(g.tenant.id,r,"otp");if(!_)throw new j(400,{message:"Code not found or expired"});if(_.expires_at<new Date().toISOString())throw new j(400,{message:"Code expired"});const x=await e.data.logins.get(g.tenant.id,_.login_id);if(!x||x.authParams.username!==i)throw new j(400,{message:"Code not found or expired"});const h=Hn(n.req);if(x.ip!==h.ip)return n.redirect(`${vt(n.env)}invalid-session?state=${x.login_id}`);if(!Xs(s,g.callbacks,{allowPathWildcards:!0}))throw new j(400,{message:`Invalid redirect URI - ${s}`});const m={client_id:t,redirect_uri:s,state:a,nonce:p,scope:c,audience:l,response_type:u},b=await as({userAdapter:e.data.users,tenant_id:g.tenant.id,email:i,provider:"email"});if(!b)throw new j(400,{message:"User not found"});return ei(n,{user:b,client:g,loginSession:x,authParams:m})});class oi extends j{constructor(t,i){super(t,i);te(this,"_code");this._code=i==null?void 0:i.code}get code(){return this._code}}async function Cv(n,e,t){const{env:i}=n,r=t.username;if(n.set("username",r),!r)throw new j(400,{message:"Username is required"});const s=await Xa({userAdapter:n.env.data.users,tenant_id:e.tenant.id,email:r,provider:"auth2"});if(!s){const _=be(n,{type:_e.FAILED_LOGIN_INCORRECT_PASSWORD,description:"Invalid user"});throw _t(n,n.env.data.logs.create(e.tenant.id,_)),new oi(403,{message:"User not found",code:"USER_NOT_FOUND"})}const a=s.linked_to?await i.data.users.get(e.tenant.id,s.linked_to):s;if(!a)throw new oi(403,{message:"User not found",code:"USER_NOT_FOUND"});n.set("connection",s.connection),n.set("user_id",a.user_id);const{password:c}=await i.data.passwords.get(e.tenant.id,s.user_id);if(!await Za.compare(t.password,c)){const _=be(n,{type:_e.FAILED_LOGIN_INCORRECT_PASSWORD,description:"Invalid password"});throw _t(n,n.env.data.logs.create(e.tenant.id,_)),new oi(403,{message:"Invalid password",code:"INVALID_PASSWORD"})}if((await i.data.logs.list(e.tenant.id,{page:0,per_page:10,include_totals:!1,q:`user_id:${a.user_id}`})).logs.filter(_=>_.type===_e.FAILED_LOGIN_INCORRECT_PASSWORD&&new Date(_.date)>new Date(Date.now()-1e3*60*5)).length>=3){const _=be(n,{type:_e.FAILED_LOGIN,description:"Too many failed login attempts"});throw _t(n,n.env.data.logs.create(e.tenant.id,_)),new oi(403,{message:"Too many failed login attempts",code:"TOO_MANY_FAILED_LOGINS"})}if(!s.email_verified&&e.email_validation==="enforced"){await fh(n,s);const _=be(n,{type:_e.FAILED_LOGIN,description:"Email not verified"});throw await n.env.data.logs.create(e.tenant.id,_),new oi(403,{message:"Email not verified",code:"EMAIL_NOT_VERIFIED"})}const g=be(n,{type:_e.SUCCESS_LOGIN,description:"Successful login",strategy_type:"Username-Password-Authentication",strategy:"Username-Password-Authentication"});return _t(n,n.env.data.logs.create(e.tenant.id,g)),a}function jv(){const n=new Uint8Array(32);return crypto.getRandomValues(n),sn.encode(n,{includePadding:!1})}function wd(){return new j(403,{res:new Response(JSON.stringify({error:"access_denied",error_description:"Wrong email or verification code."}),{status:403,headers:{"Content-Type":"application/json"}}),message:"Wrong email or verification code."})}const bd=30*60*1e3,Nv=new o.OpenAPIHono().openapi(o.createRoute({tags:["oauth"],method:"post",path:"/",request:{body:{content:{"application/json":{schema:o.z.union([o.z.object({credential_type:o.z.literal("http://auth0.com/oauth/grant-type/passwordless/otp"),otp:o.z.string(),client_id:o.z.string(),username:o.z.string().transform(n=>n.toLowerCase()),realm:o.z.enum(["email"]),scope:o.z.string().optional()}),o.z.object({credential_type:o.z.literal("http://auth0.com/oauth/grant-type/password-realm"),client_id:o.z.string(),username:o.z.string().transform(n=>n.toLowerCase()),password:o.z.string(),realm:o.z.enum(["Username-Password-Authentication"]),scope:o.z.string().optional()})])}}}},responses:{200:{description:"List of tenants"}}}),async n=>{const e=n.req.valid("json"),{client_id:t,username:i}=e;n.set("username",i);const r=await n.env.data.clients.get(t);if(!r)throw new j(400,{message:"Client not found"});n.set("client_id",t),n.set("tenant_id",r.tenant.id);const s=i.toLocaleLowerCase();let a;if("otp"in e){const p=await n.env.data.codes.get(r.tenant.id,e.otp,"otp");if(!p)throw wd();const g=await n.env.data.logins.get(r.tenant.id,p.login_id);if(!g||g.authParams.username!==s)throw wd();a=g}else if("password"in e)await Cv(n,r,{username:i,password:e.password,client_id:t}),a=await n.env.data.logins.create(r.tenant.id,{expires_at:new Date(Date.now()+bd).toISOString(),authParams:{client_id:r.id,username:s},...Hn(n.req)});else throw new j(400,{message:"Code or password required"});const c=jv(),l=Me(12),u=await n.env.data.codes.create(r.tenant.id,{code_id:Me(),code_type:"ticket",login_id:a.login_id,expires_at:new Date(Date.now()+bd).toISOString(),code_verifier:[l,c].join("|")});return n.json({login_ticket:u.code_id,co_verifier:c,co_id:l})});function Ov(n,e){var i,r,s;if(!n||e.length===0)return!1;const t=((i=vo(n))==null?void 0:i.host)??null;if(!t)return!1;for(const a of e){let c;if(a.startsWith("http://")||a.startsWith("https://")?c=((r=vo(a))==null?void 0:r.host)??null:c=((s=vo("https://"+a))==null?void 0:s.host)??null,t===c)return!0}return!1}function vo(n){try{return new URL(n)}catch{return null}}async function Bv({ctx:n,session:e,client:t,authParams:i,connection:r,login_hint:s}){const a=await n.env.data.logins.create(t.tenant.id,{expires_at:new Date(Date.now()+es*1e3).toISOString(),authParams:i,...Hn(n.req)});if(e&&s){const c=await n.env.data.users.get(t.tenant.id,e.user_id);if((c==null?void 0:c.email)===s)return ei(n,{client:t,loginSession:a,authParams:i,user:c,sessionId:e.id})}if(r==="email"&&s){const c=hh();return await n.env.data.codes.create(t.tenant.id,{code_id:c,code_type:"otp",login_id:a.login_id,expires_at:new Date(Date.now()+es*1e3).toISOString()}),await ph(n,s,c),n.redirect(`/u/enter-code?state=${a.login_id}`)}return e?n.redirect(`/u/check-account?state=${a.login_id}`):n.redirect(`/u/enter-email?state=${a.login_id}`)}function Tv(n){if(n==="Username-Password-Authentication")return"auth2";if(n==="email")return"email";throw new j(403,{message:"Invalid realm"})}async function Rv(n,e,t,i,r){var _;const{env:s}=n;n.set("connection",r);const a=await s.data.codes.get(e,t,"ticket");if(!a||a.used_at)throw new j(403,{message:"Ticket not found"});const c=await s.data.logins.get(e,a.login_id);if(!c||!c.authParams.username)throw new j(403,{message:"Session not found"});const l=await s.data.clients.get(c.authParams.client_id);if(!l)throw new j(403,{message:"Client not found"});n.set("client_id",c.authParams.client_id),await s.data.codes.used(e,t);const u=Tv(r);let p=await as({userAdapter:s.data.users,tenant_id:e,email:c.authParams.username,provider:u});p||(p=await s.data.users.create(e,{user_id:`email|${Ya()}`,email:c.authParams.username,name:c.authParams.username,provider:"email",connection:"email",email_verified:!0,is_social:!1,last_ip:"",last_login:new Date().toISOString()})),n.set("username",p.email),n.set("user_id",p.user_id);const g=await ch(n,{user:p,client:l,scope:i.scope,audience:i.audience});return ei(n,{authParams:{scope:(_=c.authParams)==null?void 0:_.scope,...i},loginSession:c,sessionId:g.id,user:p,client:l})}async function kd(n,e){return`<!DOCTYPE html>
|
|
150
150
|
<html>
|
|
151
151
|
|
|
152
152
|
<head>
|
package/dist/authhero.mjs
CHANGED
|
@@ -18466,28 +18466,50 @@ async function fv(n, e) {
|
|
|
18466
18466
|
e.refresh_token
|
|
18467
18467
|
);
|
|
18468
18468
|
if (i) {
|
|
18469
|
-
if (i.expires_at && new Date(i.expires_at) < /* @__PURE__ */ new Date())
|
|
18470
|
-
throw new N(403, {
|
|
18471
|
-
|
|
18472
|
-
|
|
18469
|
+
if (i.expires_at && new Date(i.expires_at) < /* @__PURE__ */ new Date() || i.idle_expires_at && new Date(i.idle_expires_at) < /* @__PURE__ */ new Date())
|
|
18470
|
+
throw new N(403, {
|
|
18471
|
+
message: JSON.stringify({
|
|
18472
|
+
error: "invalid_grant",
|
|
18473
|
+
error_description: "Refresh token has expired"
|
|
18474
|
+
})
|
|
18475
|
+
});
|
|
18476
|
+
} else throw new N(403, {
|
|
18477
|
+
message: JSON.stringify({
|
|
18478
|
+
error: "invalid_grant",
|
|
18479
|
+
error_description: "Invalid refresh token"
|
|
18480
|
+
})
|
|
18481
|
+
});
|
|
18482
|
+
const r = await n.env.data.users.get(
|
|
18473
18483
|
t.tenant.id,
|
|
18474
|
-
i.
|
|
18484
|
+
i.user_id
|
|
18475
18485
|
);
|
|
18476
18486
|
if (!r)
|
|
18477
|
-
throw new N(403, { message: "Session not found" });
|
|
18478
|
-
const s = await n.env.data.users.get(t.tenant.id, r.user_id);
|
|
18479
|
-
if (!s)
|
|
18480
18487
|
throw new N(403, { message: "User not found" });
|
|
18481
|
-
const
|
|
18488
|
+
const s = i.resource_servers[0];
|
|
18489
|
+
if (i.idle_expires_at) {
|
|
18490
|
+
const o = new Date(
|
|
18491
|
+
Date.now() + 2592e6
|
|
18492
|
+
// 30 days
|
|
18493
|
+
);
|
|
18494
|
+
await n.env.data.refreshTokens.update(t.tenant.id, i.id, {
|
|
18495
|
+
idle_expires_at: o.toISOString(),
|
|
18496
|
+
last_exchanged_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
18497
|
+
device: {
|
|
18498
|
+
...i.device,
|
|
18499
|
+
last_ip: n.req.header["x-real-ip"] || "",
|
|
18500
|
+
last_user_agent: n.req.header["user-agent"] || ""
|
|
18501
|
+
}
|
|
18502
|
+
});
|
|
18503
|
+
}
|
|
18482
18504
|
return ei(n, {
|
|
18483
|
-
user:
|
|
18505
|
+
user: r,
|
|
18484
18506
|
client: t,
|
|
18485
18507
|
refreshToken: i.id,
|
|
18486
|
-
sessionId:
|
|
18508
|
+
sessionId: i.session_id,
|
|
18487
18509
|
authParams: {
|
|
18488
18510
|
client_id: t.id,
|
|
18489
|
-
audience:
|
|
18490
|
-
scope:
|
|
18511
|
+
audience: s == null ? void 0 : s.audience,
|
|
18512
|
+
scope: s == null ? void 0 : s.scopes,
|
|
18491
18513
|
response_mode: rn.WEB_MESSAGE
|
|
18492
18514
|
}
|
|
18493
18515
|
});
|