diff --git a/bundle.js b/bundle.js index 6d10205..dec9470 100644 --- a/bundle.js +++ b/bundle.js @@ -1 +1 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),r=require("crypto-js"),t=require("jwt-decode");function s(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var o=s(e),a=s(t);const c=process.env.KINDE_SITE_URL,i=process.env.KINDE_ISSUER_URL,n=process.env.KINDE_POST_LOGOUT_REDIRECT_URL,u={initialState:{user:null,isLoading:!0,checkSession:null},SESSION_PREFIX:"pkce-verifier",redirectURL:c,issuerURL:i,clientID:process.env.KINDE_CLIENT_ID,clientSecret:process.env.KINDE_CLIENT_SECRET,postLogoutRedirectURL:n,audience:process.env.KINDE_AUDIENCE,responseType:"code",scope:"openid profile email",codeChallengeMethod:"S256",redirectRoutes:{callback:"/api/auth/kinde_callback"},issuerRoutes:{logout:"/logout",login:"/oauth2/auth",register:"/oauth2/auth",token:"/oauth2/token",profile:"/oauth2/v2/user_profile"}},d=()=>{throw new Error("Oops! Seems like you forgot to wrap your app in .")},l=e.createContext({...u.initialState,user:d,isLoading:d}),_=require("crypto"),h=()=>_.randomBytes(28).toString("hex");function g(){const e=h(),t=function(e){return r.SHA256(e).toString(r.enc.Base64url)}(e);return{code_verifier:e,code_challenge:t}}var p=require("cookie");const R=(e,r,t)=>{const s=h(),{code_challenge:o,code_verifier:a}=g();return r.setHeader("Set-Cookie",p.serialize(`${u.SESSION_PREFIX}-${s}`,a,{httpOnly:!0,maxAge:t})),{state:s,code_challenge:o}};var L=require("cookie");var k=require("cookie");var y=require("cookie");exports.KindeProvider=({children:r})=>{const[t,s]=e.useState({...u.initialState}),a="/api/auth/me",c=e.useCallback((async()=>{try{const e=await(async e=>{let r;try{r=await fetch(e)}catch{throw new RequestError(0)}if(r.ok)return r.json();r.status})(a);s((r=>({...r,user:e,error:void 0})))}catch(e){s((r=>({...r,isLoading:!1,error:e})))}}),[a]);e.useEffect((()=>{t.user||(async()=>{await c(),s((e=>({...e,isLoading:!1})))})()}),[t.user]);const{user:i,error:n,isLoading:d}=t;return o.default.createElement(l.Provider,{value:{user:i,error:n,isLoading:d,isAuthenticated:!!i}},r)},exports.handleAuth=()=>async function(e,r){let{query:{kindeAuth:t}}=e;switch(t=Array.isArray(t)?t[0]:t,t){case"login":return await(async(e,r)=>{const t=e.query,{org_code:s,is_create_org:o,org_name:a=""}=t,{state:c,code_challenge:i}=R(0,r,60),n=new URL(u.issuerURL+u.issuerRoutes.login);let d={redirect_uri:u.redirectURL+u.redirectRoutes.callback,client_id:u.clientID,response_type:u.responseType,scope:u.scope,code_challenge:i,code_challenge_method:u.codeChallengeMethod,state:c,start_page:"login",audience:u.audience};s&&(d.org_code=s),o&&(d.is_create_org=o,d.org_name=a),n.search=new URLSearchParams(d),r.redirect(n.href)})(e,r);case"register":return await(async(e,r)=>{const t=e.query,{org_code:s,is_create_org:o,org_name:a=""}=t,{state:c,code_challenge:i}=R(0,r,180),n=new URL(u.issuerURL+u.issuerRoutes.register);let d={redirect_uri:u.redirectURL+u.redirectRoutes.callback,client_id:u.clientID,response_type:u.responseType,scope:u.scope,code_challenge:i,code_challenge_method:u.codeChallengeMethod,state:c,start_page:"registration",audience:u.audience};s&&(d.org_code=s),o&&(d.is_create_org=o,d.org_name=a),n.search=new URLSearchParams(d),r.redirect(n.href)})(e,r);case"me":return await(async(e,r)=>{const t=k.parse(e.headers.cookie||"").kinde_token;if(t){const e=JSON.parse(t);try{const t=await fetch(u.issuerURL+u.issuerRoutes.profile,{headers:new Headers({Authorization:"Bearer "+e.access_token})}),s=await t.json();r.send(s)}catch(e){console.log(e)}}else r.status(401).send("Unauthorized")})(e,r);case"logout":return await(async(e,r)=>{r.setHeader("Set-Cookie",L.serialize("kinde_token",null,{httpOnly:!0,expires:new Date(0),sameSite:"lax",path:"/"}));const t=new URL(u.issuerURL+u.issuerRoutes.logout);t.searchParams.set("redirect",u.postLogoutRedirectURL),r.redirect(t.href)})(0,r);case"kinde_callback":return await(async(e,r)=>{const{code:t,state:s}=e.query,o=y.parse(e.headers.cookie||"")[`${u.SESSION_PREFIX}-${s}`];if(o){try{const e=await fetch(u.issuerURL+u.issuerRoutes.token,{method:"POST",headers:new Headers({"Content-type":"application/x-www-form-urlencoded; charset=UTF-8"}),body:new URLSearchParams({client_id:u.clientID,client_secret:u.clientSecret,code:t,code_verifier:o,grant_type:"authorization_code",redirect_uri:u.redirectURL+u.redirectRoutes.callback})}),s=await e.json(),c=a.default(s.access_token,{header:!0}),i=a.default(s.access_token);let n=!0;if(null!=u.audience&&(n=i.aud==u.audience),i.iss==u.issuerURL&&"RS256"==c.alg&&i.exp>Math.floor(Date.now()/1e3)&&n)r.setHeader("Set-Cookie",y.serialize("kinde_token",JSON.stringify(s),{httpOnly:!0,maxAge:3600,sameSite:"strict",secure:!0,path:"/"}));else{console.error("One or more of the claims were not verified.");const e=new URL(u.issuerURL+u.issuerRoutes.logout);e.searchParams.set("redirect",u.postLogoutRedirectURL),r.redirect(e.href)}}catch(e){console.error(e)}r.redirect(u.redirectURL)}else{const e=new URL(u.issuerURL+u.issuerRoutes.logout);e.searchParams.set("redirect",u.postLogoutRedirectURL),r.redirect(e.href)}})(e,r);case"create_org":return await(async(e,r)=>{const t=e.query,{org_name:s="",start_page:o="registration"}=t,{state:a,code_challenge:c}=R(0,r,60),i=new URL(u.issuerURL+u.issuerRoutes.login);let n={redirect_uri:u.redirectURL+u.redirectRoutes.callback,client_id:u.clientID,response_type:u.responseType,scope:u.scope,code_challenge:c,code_challenge_method:u.codeChallengeMethod,state:a,start_page:o,is_create_org:!0,org_name:s,audience:u.audience};i.search=new URLSearchParams(n),r.redirect(i.href)})(e,r);case"get_token":return await(async(e,r)=>{e.cookies.kinde_token?r.status(200).json(JSON.parse(e.cookies.kinde_token)):r.status(500).json({message:"There is no kinde_token, you are not authenticated. Try logging in."})})(e,r);default:return r.status(404).end()}},exports.useKindeAuth=()=>e.useContext(l); +"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),r=require("crypto-js"),t=require("jwt-decode");function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var s=o(e),a=o(t);const c=process.env.KINDE_SITE_URL,i=process.env.KINDE_ISSUER_URL,n=process.env.KINDE_POST_LOGOUT_REDIRECT_URL,u={initialState:{user:null,isLoading:!0,checkSession:null},SESSION_PREFIX:"pkce-verifier",redirectURL:c,issuerURL:i,clientID:process.env.KINDE_CLIENT_ID,clientSecret:process.env.KINDE_CLIENT_SECRET,postLogoutRedirectURL:n,audience:process.env.KINDE_AUDIENCE,responseType:"code",scope:"openid profile email",codeChallengeMethod:"S256",redirectRoutes:{callback:"/api/auth/kinde_callback"},issuerRoutes:{logout:"/logout",login:"/oauth2/auth",register:"/oauth2/auth",token:"/oauth2/token",profile:"/oauth2/v2/user_profile"}},d=()=>{throw new Error("Oops! Seems like you forgot to wrap your app in .")},l=e.createContext({...u.initialState,user:d,isLoading:d}),_=require("crypto"),h=()=>_.randomBytes(28).toString("hex");function g(){const e=h(),t=function(e){return r.SHA256(e).toString(r.enc.Base64url)}(e);return{code_verifier:e,code_challenge:t}}var p=require("cookie");const R=(e,r,t)=>{const o=h(),{code_challenge:s,code_verifier:a}=g();return r.setHeader("Set-Cookie",p.serialize(`${u.SESSION_PREFIX}-${o}`,a,{httpOnly:!0,maxAge:t})),{state:o,code_challenge:s}};var k=require("cookie");var y=require("cookie");var L=require("cookie");exports.KindeProvider=({children:r})=>{const[t,o]=e.useState({...u.initialState}),a="/api/auth/me",c=e.useCallback((async()=>{try{const e=await(async e=>{let r;try{r=await fetch(e)}catch{throw new RequestError(0)}if(r.ok)return r.json();r.status})(a);o((r=>({...r,user:e,error:void 0})))}catch(e){o((r=>({...r,isLoading:!1,error:e})))}}),[a]);e.useEffect((()=>{t.user||(async()=>{await c(),o((e=>({...e,isLoading:!1})))})()}),[t.user]);const{user:i,error:n,isLoading:d}=t;return s.default.createElement(l.Provider,{value:{user:i,error:n,isLoading:d,isAuthenticated:!!i}},r)},exports.handleAuth=()=>async function(e,r){let{query:{kindeAuth:t}}=e;switch(t=Array.isArray(t)?t[0]:t,t){case"login":return await(async(e,r)=>{const t=e.query,{org_code:o,is_create_org:s,org_name:a=""}=t,{state:c,code_challenge:i}=R(0,r,60),n=new URL(u.issuerURL+u.issuerRoutes.login);let d={redirect_uri:u.redirectURL+u.redirectRoutes.callback,client_id:u.clientID,response_type:u.responseType,scope:u.scope,code_challenge:i,code_challenge_method:u.codeChallengeMethod,state:c,start_page:"login"};o&&(d.org_code=o),s&&(d.is_create_org=s,d.org_name=a),u.audience&&(d.audience=u.audience),n.search=new URLSearchParams(d),r.redirect(n.href)})(e,r);case"register":return await(async(e,r)=>{const t=e.query,{org_code:o,is_create_org:s,org_name:a=""}=t,{state:c,code_challenge:i}=R(0,r,180),n=new URL(u.issuerURL+u.issuerRoutes.register);let d={redirect_uri:u.redirectURL+u.redirectRoutes.callback,client_id:u.clientID,response_type:u.responseType,scope:u.scope,code_challenge:i,code_challenge_method:u.codeChallengeMethod,state:c,start_page:"registration"};o&&(d.org_code=o),s&&(d.is_create_org=s,d.org_name=a),u.audience&&(d.audience=u.audience),n.search=new URLSearchParams(d),r.redirect(n.href)})(e,r);case"me":return await(async(e,r)=>{const t=y.parse(e.headers.cookie||"").kinde_token;if(t){const e=JSON.parse(t);try{const t=await fetch(u.issuerURL+u.issuerRoutes.profile,{headers:new Headers({Authorization:"Bearer "+e.access_token})}),o=await t.json();r.send(o)}catch(e){console.log(e)}}else r.status(401).send({message:"Unauthorized"})})(e,r);case"logout":return await(async(e,r)=>{r.setHeader("Set-Cookie",k.serialize("kinde_token",null,{httpOnly:!0,expires:new Date(0),sameSite:"lax",path:"/"}));const t=new URL(u.issuerURL+u.issuerRoutes.logout);t.searchParams.set("redirect",u.postLogoutRedirectURL),r.redirect(t.href)})(0,r);case"kinde_callback":return await(async(e,r)=>{const{code:t,state:o}=e.query,s=L.parse(e.headers.cookie||"")[`${u.SESSION_PREFIX}-${o}`];if(s){try{const e=await fetch(u.issuerURL+u.issuerRoutes.token,{method:"POST",headers:new Headers({"Content-type":"application/x-www-form-urlencoded; charset=UTF-8"}),body:new URLSearchParams({client_id:u.clientID,client_secret:u.clientSecret,code:t,code_verifier:s,grant_type:"authorization_code",redirect_uri:u.redirectURL+u.redirectRoutes.callback})}),o=await e.json(),c=a.default(o.access_token,{header:!0}),i=a.default(o.access_token);let n=i.aud==u.audience;i.iss==u.issuerURL&&"RS256"==c.alg&&i.exp>Math.floor(Date.now()/1e3)&&n?r.setHeader("Set-Cookie",L.serialize("kinde_token",JSON.stringify(o),{httpOnly:!0,maxAge:3600,sameSite:"strict",secure:!0,path:"/"})):console.error("One or more of the claims were not verified.")}catch(e){console.error(e)}r.redirect(u.redirectURL)}else{const e=new URL(u.issuerURL+u.issuerRoutes.logout);e.searchParams.set("redirect",u.postLogoutRedirectURL),r.redirect(e.href)}})(e,r);case"create_org":return await(async(e,r)=>{const t=e.query,{org_name:o="",start_page:s="registration"}=t,{state:a,code_challenge:c}=R(0,r,60),i=new URL(u.issuerURL+u.issuerRoutes.login);let n={redirect_uri:u.redirectURL+u.redirectRoutes.callback,client_id:u.clientID,response_type:u.responseType,scope:u.scope,code_challenge:c,code_challenge_method:u.codeChallengeMethod,state:a,start_page:s,is_create_org:!0,org_name:o,audience:u.audience};i.search=new URLSearchParams(n),r.redirect(i.href)})(e,r);case"get_token":return await(async(e,r)=>{e.cookies.kinde_token?r.status(200).json(JSON.parse(e.cookies.kinde_token)):r.status(500).json({message:"There is no kinde_token, you are not authenticated. Try logging in."})})(e,r);default:return r.status(404).end()}},exports.useKindeAuth=()=>e.useContext(l); diff --git a/index.d.ts b/index.d.ts index 56fc43c..2a0f444 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,12 +1,12 @@ import React from "react"; -export function useKindeAuth(): State; -export function KindeProvider({ +export declare function useKindeAuth(): State; +export declare function KindeProvider({ children, }: { children: any; }): React.Provider; -export function handleAuth(): any; +export declare function handleAuth(): any; export type User = { id: string; name: string | null; diff --git a/src/handlers/callback.js b/src/handlers/callback.js index fc2b292..71863f7 100644 --- a/src/handlers/callback.js +++ b/src/handlers/callback.js @@ -31,12 +31,7 @@ export const callback = async (req, res) => { const accessTokenHeader = jwt_decode(data.access_token, { header: true }); const accessTokenPayload = jwt_decode(data.access_token); - let isAudienceValid = true; - - if (config.audience != undefined) { - isAudienceValid = accessTokenPayload.aud == config.audience; - } - + let isAudienceValid = accessTokenPayload.aud == config.audience; if ( accessTokenPayload.iss == config.issuerURL && accessTokenHeader.alg == "RS256" && @@ -55,11 +50,6 @@ export const callback = async (req, res) => { ); } else { console.error("One or more of the claims were not verified."); - const logoutURL = new URL( - config.issuerURL + config.issuerRoutes.logout - ); - logoutURL.searchParams.set("redirect", config.postLogoutRedirectURL); - res.redirect(logoutURL.href); } } catch (err) { console.error(err); diff --git a/src/handlers/login.js b/src/handlers/login.js index 8e4e94b..9054fc3 100644 --- a/src/handlers/login.js +++ b/src/handlers/login.js @@ -18,7 +18,6 @@ export const login = async (req, res) => { code_challenge_method: config.codeChallengeMethod, state, start_page: "login", - audience: config.audience, }; if (org_code) { @@ -30,6 +29,10 @@ export const login = async (req, res) => { searchParams.org_name = org_name; } + if (config.audience) { + searchParams.audience = config.audience; + } + loginURL.search = new URLSearchParams(searchParams); res.redirect(loginURL.href); diff --git a/src/handlers/me.js b/src/handlers/me.js index b484762..e1ca766 100644 --- a/src/handlers/me.js +++ b/src/handlers/me.js @@ -21,6 +21,8 @@ export const me = async (req, res) => { console.log(err); } } else { - res.status(401).send("Unauthorized"); + res.status(401).send({ + message: "Unauthorized", + }); } }; diff --git a/src/handlers/register.js b/src/handlers/register.js index acb77a5..6ca1264 100644 --- a/src/handlers/register.js +++ b/src/handlers/register.js @@ -18,7 +18,6 @@ export const register = async (req, res) => { code_challenge_method: config.codeChallengeMethod, state, start_page: "registration", - audience: config.audience, }; if (org_code) { @@ -30,6 +29,10 @@ export const register = async (req, res) => { searchParams.org_name = org_name; } + if (config.audience) { + searchParams.audience = config.audience; + } + registerURL.search = new URLSearchParams(searchParams); res.redirect(registerURL.href);