@ymys/directus-extension-sso 2.0.4 → 2.0.6
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/index.js +3 -1
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -1 +1,3 @@
|
|
|
1
|
-
import{createRequire as t}from"module";import e from"node:crypto";const n=t(import.meta.url),{version:o}=n("../package.json");var r={id:"sso",handler:(t,n)=>{const{env:r,logger:a,services:i,database:s,getSchema:c}=n,l=r.KEYCLOAK_URL||"http://keycloak:8080",d=r.KEYCLOAK_REALM||"testing",u=r.KEYCLOAK_ADMIN_USER||"admin",p=r.KEYCLOAK_ADMIN_PASSWORD||"admin",f=r.PUBLIC_URL||"http://localhost:8055",g=r.MOBILE_APP_SCHEME||"portalpipq",h=r.MOBILE_APP_CALLBACK_PATH||"/auth/callback",m=r.GOOGLE_CALLBACK_PATH||"/auth/callback/google",y=r.KEYCLOAK_CLIENT_ID||"admin-cli",k=r.COOKIE_DOMAIN||null,b="false"!==r.COOKIE_SECURE,x=r.COOKIE_SAME_SITE||"lax",w=r.SESSION_COOKIE_NAME||"directus_session_token",$=r.REFRESH_TOKEN_COOKIE_NAME||"directus_refresh_token",v="directus_session_token";function _(t){if("browser"===t.query.type)return!0;if("mobile"===t.query.type)return!1;if(t.query.app_scheme||t.query.app_path)return!1;const e=t.headers["user-agent"]||"";return/Mozilla|Chrome|Safari|Firefox|Edge|Opera/i.test(e)&&!/Mobile.*App|ReactNative|Expo/i.test(e)}async function A(t,e){const n=t.headers.cookie;if(!n)return null;const o=n.split(";").map(t=>t.trim()).filter(t=>t.startsWith(`${e}=`)).map(t=>t.substring(e.length+1));if(0===o.length)return null;a.info(`🔍 [${e}] Found ${o.length} possible tokens. Trying them...`);for(let t=0;t<o.length;t++){const n=o[t];try{const o=await fetch(`${f}/users/me`,{headers:{Cookie:`${e}=${n}`}});if(o.ok){const r=await o.json();return a.info(`✅ [${e}] Token #${t+1} succeeded for ${r.data.email}`),{token:n,userData:r.data}}a.info(`❌ [${e}] Token #${t+1} failed (${o.status})`)}catch(n){a.error(`⚠️ [${e}] Error trying token #${t+1}: ${n.message}`)}}return null}async function E(t){const e=t.headers.cookie;if(!e)return null;const n=e.split(";").map(t=>t.trim()).map(t=>{const e=t.split("=");return e.length>1?e[1]:null}).filter(t=>t&&t.startsWith("eyJ")&&t.length>50);if(0===n.length)return null;a.info(`🔍 [MEGA] Found ${n.length} potential JWTs in cookies. Trying them...`);for(let t=0;t<n.length;t++){const e=n[t];try{const n=await fetch(`${f}/users/me`,{headers:{Authorization:`Bearer ${e}`}});if(n.ok){const o=await n.json();return a.info(`✅ [MEGA] Token #${t+1} succeeded for ${o.data.email}`),{token:e,userData:o.data}}}catch(t){}}return null}async function S(t){const e=t.cookies[$];if(!e)return null;a.info(`🔄 [REFRESH] Attempting to use ${$}...`);try{const t=await fetch(`${f}/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refresh_token:e})});if(t.ok){const e=(await t.json()).data.access_token;a.info("✅ [REFRESH] Successfully refreshed session");const n=await fetch(`${f}/users/me`,{headers:{Authorization:`Bearer ${e}`}});if(n.ok){return{token:e,userData:(await n.json()).data}}}}catch(t){a.error("❌ [REFRESH] Failed: "+t.message)}return null}a.info("🚀 Mobile Auth Proxy Extension loaded"),a.info("🔐 Keycloak URL: "+l),a.info("🌐 Keycloak Realm: "+d),a.info("📡 Public URL: "+f),a.info("🍪 Session Cookie Name: "+w),a.info("🍪 Refresh Token Cookie Name: "+$),a.info("📱 Mobile App Scheme: "+g+"://"+h),a.info("🔵 Google OAuth enabled"),t.get("/health",(t,e)=>{e.json({status:"ok",service:"directus-extension-sso",version:o})}),t.get("/mobile-callback",async(t,e)=>{const n=_(t);a.info(`${n?"🌐":"📱"} ${n?"Browser":"Mobile"} callback received`),a.info("Host Header: "+t.headers.host),a.info("Cookies Header: "+t.headers.cookie),a.info("Parsed Cookies: "+JSON.stringify(t.cookies)),a.info("Query: "+JSON.stringify(t.query));try{let o=null;if(w!==v&&(o=await A(t,w)),o||(o=await A(t,v)),o||(o=await E(t)),o||(o=await S(t)),!o)return a.error("❌ No valid session or refresh token found in any cookies"),e.send(`\n\t\t\t\t\t\t<html>\n\t\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t\t<h2>Authentication Failed</h2>\n\t\t\t\t\t\t\t\t<p>No valid session found. Please try logging in again.</p>\n\t\t\t\t\t\t\t\t<div style="font-size: 11px; color: #999; margin-top: 20px; text-align: left;">\n\t\t\t\t\t\t\t\t\t<strong>Debug Info (v1.5.4):</strong><br>\n\t\t\t\t\t\t\t\t\tInstance: ${w}<br>\n\t\t\t\t\t\t\t\t\tURL: ${f}<br>\n\t\t\t\t\t\t\t\t\tHost: ${t.headers.host}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<a href="${f}/auth/login/keycloak" style="display: inline-block; margin-top: 20px;">Try Again</a>\n\t\t\t\t\t\t\t</body>\n\t\t\t\t\t\t</html>\n\t\t\t\t\t`);const{token:r,userData:i}=o,s=i.id,c=i.email;a.info("👤 User authenticated: "+s+", "+c);const l=r;if(a.info("🎫 Using session token as access token"),n){a.info("🌐 Browser request detected - maintaining session"),e.cookie(w,r,{httpOnly:!0,secure:b,domain:k,sameSite:x,maxAge:6048e5,path:"/"}),w!==v&&e.cookie(v,"",{maxAge:0,path:"/"});let n=t.query.redirect_uri||t.query.redirect||"/";try{if(n.startsWith("http")){const t=new URL(n);t.searchParams.set("access_token",l),t.searchParams.set("user_id",s),t.searchParams.set("email",c||""),n=t.toString()}}catch(t){a.error("❌ Failed to parse Web redirect URL: "+n)}return a.info("🔄 Redirecting browser to: "+n),e.redirect(n)}const d=t.query.app_scheme||g,u=`${d}://${(t.query.app_path||h).replace(/^\/+/,"")}?access_token=${l}&user_id=${s}&email=${encodeURIComponent(c||"")}`;return a.info("🔄 Attempting AUTO-REDIRECT to app: "+u),e.setHeader("Location",u),e.status(302).send(`\n\t\t\t\t\t<html>\n\t\t\t\t\t\t<head>\n\t\t\t\t\t\t\t<title>Authenticating...</title>\n\t\t\t\t\t\t\t<meta name="viewport" content="width=device-width, initial-scale=1">\n\t\t\t\t\t\t\t<meta http-equiv="refresh" content="0;url=${u}">\n\t\t\t\t\t\t\t<style>\n\t\t\t\t\t\t\t\tbody { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; \n\t\t\t\t\t\t\t\t padding: 40px; text-align: center; background: #fff; }\n\t\t\t\t\t\t\t\t.lds-dual-ring { display: inline-block; width: 40px; height: 40px; margin-bottom: 20px; }\n\t\t\t\t\t\t\t\t.lds-dual-ring:after { content: " "; display: block; width: 32px; height: 32px; margin: 8px; \n\t\t\t\t\t\t\t\t border-radius: 50%; border: 4px solid #4f46e5; \n\t\t\t\t\t\t\t\t\t\t\t\t\t border-color: #4f46e5 transparent #4f46e5 transparent; \n\t\t\t\t\t\t\t\t\t\t\t\t\t animation: lds-dual-ring 1.2s linear infinite; }\n\t\t\t\t\t\t\t\t@keyframes lds-dual-ring { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }\n\t\t\t\t\t\t\t\t.btn { display: inline-block; padding: 12px 24px; background: #4f46e5; color: white; \n\t\t\t\t\t\t\t\t text-decoration: none; border-radius: 6px; font-weight: 500; margin-top: 20px; }\n\t\t\t\t\t\t\t</style>\n\t\t\t\t\t\t</head>\n\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t<div class="lds-dual-ring"></div>\n\t\t\t\t\t\t\t<h2>Finishing Login...</h2>\n\t\t\t\t\t\t\t<p>You are being redirected back to the app.</p>\n\t\t\t\t\t\t\t<p style="font-size: 14px; color: #666; margin-top: 20px;">If the app doesn't open automatically, please click below:</p>\n\t\t\t\t\t\t\t<a id="redirect-btn" href="${u}" class="btn">Return to App</a>\n\t\t\t\t\t\t\t<script>\n\t\t\t\t\t\t\t\t// JavaScript fallback for auto-redirect\n\t\t\t\t\t\t\t\twindow.onload = function() {\n\t\t\t\t\t\t\t\t\twindow.location.href = "${u}";\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t<\/script>\n\t\t\t\t\t\t</body>\n\t\t\t\t\t</html>\n\t\t\t\t`)}catch(t){a.error("❌ Error in callback:",t),e.status(500).send(`\n\t\t<html>\n\t\t\t<body>\n\t\t\t\t<h2>Error</h2>\n\t\t\t\t<p>${t.message}</p>\n\t\t\t\t<a href="${f}/auth/login/keycloak">Try Again</a>\n\t\t\t</body>\n\t\t</html>\n\t`)}}),t.get("/google-callback",async(t,e)=>{const n=_(t);a.info(`${n?"🌐":"📱"} ${n?"Browser":"Mobile"} Google callback received`),a.info("Cookies: "+JSON.stringify(t.cookies)),a.info("Query: "+JSON.stringify(t.query));try{let o=null;if(t.query.access_token&&(a.info("🎟️ Found access_token in URL query string! Bypassing cookie check entirely."),o={access_token:t.query.access_token,refresh_token:t.query.refresh_token||null,expires:t.query.expires||null}),o||w===v||(o=await A(t,w)),o||(o=await A(t,v)),o||(o=await E(t)),o||(o=await S(t)),!o)return a.error("❌ No valid session or refresh token found in any cookies (Google)"),e.send(`\n\t\t\t\t\t\t<html>\n\t\t\t\t\t\t\t<head>\n\t\t\t\t\t\t\t\t<title>Authentication Failed</title>\n\t\t\t\t\t\t\t\t<style>\n\t\t\t\t\t\t\t\t\tbody { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; \n\t\t\t\t\t\t\t\t\t padding: 40px; text-align: center; background: #f5f5f5; }\n\t\t\t\t\t\t\t\t\t.container { max-width: 500px; margin: 0 auto; background: white; \n\t\t\t\t\t\t\t\t\t padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }\n\t\t\t\t\t\t\t\t\th2 { color: #e74c3c; }\n\t\t\t\t\t\t\t\t\t.debug { font-size: 11px; color: #999; margin-top: 20px; text-align: left; }\n\t\t\t\t\t\t\t\t</style>\n\t\t\t\t\t\t\t</head>\n\t\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t\t<div class="container">\n\t\t\t\t\t\t\t\t\t<h2>Authentication Failed</h2>\n\t\t\t\t\t\t\t\t\t<p>No valid session found. Please close this and try logging in again.</p>\n\t\t\t\t\t\t\t\t\t<div class="debug">\n\t\t\t\t\t\t\t\t\t\t<strong>Debug Info (v1.5.4):</strong><br>\n\t\t\t\t\t\t\t\t\t\tInstance: ${w} | Google\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</body>\n\t\t\t\t\t\t</html>\n\t\t\t\t\t`);const{token:r,userData:i}=o,s=i.id,c=i.email,l=i.first_name||i.email;a.info("👤 User authenticated via Google: "+s+", "+c);const d=r;if(a.info("🎫 Using session token as access token"),n){a.info("🌐 Browser request detected - maintaining session"),e.cookie(w,r,{httpOnly:!0,secure:b,domain:k,sameSite:x,maxAge:6048e5,path:"/"}),w!==v&&e.cookie(v,"",{maxAge:0,path:"/"});let n=t.query.redirect_uri||t.query.redirect||"/";try{if(n.startsWith("http")){const t=new URL(n);t.searchParams.set("access_token",d),t.searchParams.set("user_id",s),t.searchParams.set("email",c||""),t.searchParams.set("provider","google"),n=t.toString()}}catch(t){a.error("❌ Failed to parse Web redirect URL: "+n)}return a.info("🔄 Redirecting browser to: "+n),e.send(`\n\t\t\t\t\t\t<html>\n\t\t\t\t\t\t\t<head>\n\t\t\t\t\t\t\t\t<title>Login Successful</title>\n\t\t\t\t\t\t\t\t<meta http-equiv="refresh" content="2;url=${n}">\n\t\t\t\t\t\t\t\t<style>\n\t\t\t\t\t\t\t\t\tbody { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; \n\t\t\t\t\t\t\t\t\t padding: 40px; text-align: center; background: #f5f5f5; }\n\t\t\t\t\t\t\t\t\t.container { max-width: 500px; margin: 0 auto; background: white; \n\t\t\t\t\t\t\t\t\t padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }\n\t\t\t\t\t\t\t\t\th2 { color: #27ae60; }\n\t\t\t\t\t\t\t\t\t.checkmark { font-size: 48px; color: #27ae60; margin-bottom: 20px; }\n\t\t\t\t\t\t\t\t\tp { color: #666; margin: 10px 0; }\n\t\t\t\t\t\t\t\t\t.spinner { border: 3px solid #f3f3f3; border-top: 3px solid #4285f4; \n\t\t\t\t\t\t\t\t\t border-radius: 50%; width: 40px; height: 40px; \n\t\t\t\t\t\t\t\t\t animation: spin 1s linear infinite; margin: 20px auto; }\n\t\t\t\t\t\t\t\t\t@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }\n\t\t\t\t\t\t\t\t\ta { color: #4285f4; text-decoration: none; }\n\t\t\t\t\t\t\t\t\ta:hover { text-decoration: underline; }\n\t\t\t\t\t\t\t\t\t.google-icon { color: #4285f4; margin-right: 5px; }\n\t\t\t\t\t\t\t\t</style>\n\t\t\t\t\t\t\t</head>\n\t\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t\t<div class="container">\n\t\t\t\t\t\t\t\t\t<div class="checkmark">✓</div>\n\t\t\t\t\t\t\t\t\t<h2><span class="google-icon">🔵</span>Google Login Successful!</h2>\n\t\t\t\t\t\t\t\t\t<p>Welcome, ${l}!</p>\n\t\t\t\t\t\t\t\t\t<p>Your session has been saved. You can now access other services using the same login.</p>\n\t\t\t\t\t\t\t\t\t<div class="spinner"></div>\n\t\t\t\t\t\t\t\t\t<p style="margin-top: 20px;">Redirecting you automatically...</p>\n\t\t\t\t\t\t\t\t\t<p style="font-size: 14px; margin-top: 20px;">\n\t\t\t\t\t\t\t\t\t\t<a href="${n}">Click here if not redirected automatically</a>\n\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</body>\n\t\t\t\t\t\t</html>\n\t\t\t\t\t`)}a.info("📱 Mobile app request - redirecting with token");const u=t.query.app_scheme||g,p=t.query.app_path||m,f=new URL(`${u}://${p.replace(/^\/+/,"")}`);return f.searchParams.set("access_token",d),f.searchParams.set("user_id",s),f.searchParams.set("email",c||""),f.searchParams.set("provider","google"),a.info("🔄 Redirecting to app (Google): "+f.toString()),a.info("🚀 Performing direct 302 redirect to app: "+f.toString()),e.redirect(302,f.toString())}catch(t){a.error("❌ Error in Google callback:",t),e.status(500).send(`\n\t\t\t\t\t<html>\n\t\t\t\t\t\t<head>\n\t\t\t\t\t\t\t<title>Error</title>\n\t\t\t\t\t\t\t<style>\n\t\t\t\t\t\t\t\tbody { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; \n\t\t\t\t\t\t\t\t padding: 40px; text-align: center; background: #f5f5f5; }\n\t\t\t\t\t\t\t\t.container { max-width: 500px; margin: 0 auto; background: white; \n\t\t\t\t\t\t\t\t padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }\n\t\t\t\t\t\t\t\th2 { color: #e74c3c; }\n\t\t\t\t\t\t\t\t.error-icon { font-size: 48px; color: #e74c3c; margin-bottom: 20px; }\n\t\t\t\t\t\t\t\tpre { background: #f8f8f8; padding: 15px; border-radius: 4px; \n\t\t\t\t\t\t\t\t text-align: left; overflow-x: auto; font-size: 12px; }\n\t\t\t\t\t\t\t\ta { display: inline-block; margin-top: 20px; padding: 10px 20px; \n\t\t\t\t\t\t\t\t background: #4285f4; color: white; text-decoration: none; border-radius: 4px; }\n\t\t\t\t\t\t\t\ta:hover { background: #357ae8; }\n\t\t\t\t\t\t\t</style>\n\t\t\t\t\t\t</head>\n\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t<div class="container">\n\t\t\t\t\t\t\t\t<div class="error-icon">⚠️</div>\n\t\t\t\t\t\t\t\t<h2>Error</h2>\n\t\t\t\t\t\t\t\t<p>An error occurred during Google authentication:</p>\n\t\t\t\t\t\t\t\t<pre>${t.message}</pre>\n\t\t\t\t\t\t\t\t<a href="${f}/auth/login/google">Try Again</a>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</body>\n\t\t\t\t\t</html>\n\t\t\t\t`)}}),t.post("/mobile-logout",async(t,e)=>{a.info("🚪 Logout request received");try{const n=t.headers.authorization,o=n?.replace("Bearer ","");if(!o)return e.status(400).json({error:"No token provided",message:"Authorization header with Bearer token is required"});a.info("🎫 Token received: "+o.substring(0,20)+"...");let r=null;try{const t=await fetch(`${f}/users/me`,{headers:{Authorization:`Bearer ${o}`}});if(t.ok){r=(await t.json()).data.email,a.info("👤 User email: "+r)}}catch(t){a.error("⚠️ Error getting user info: "+t.message)}try{const t=await fetch(`${f}/auth/logout`,{method:"POST",headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json"},body:JSON.stringify({refresh_token:o})});t.ok?a.info("✅ Directus session invalidated"):a.info("⚠️ Directus logout response: "+t.status)}catch(t){a.error("⚠️ Error logging out from Directus: "+t.message)}if(r)try{a.info("🔐 Getting Keycloak admin token...");const t=await async function(){try{const t=await fetch(`${l}/realms/master/protocol/openid-connect/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"password",client_id:y,username:u,password:p}).toString()});if(!t.ok)throw new Error("Failed to get admin token");return(await t.json()).access_token}catch(t){return a.error("Error getting admin token:",t),null}}();if(t){a.info("🔍 Looking up Keycloak user...");const e=await async function(t,e){try{const n=await fetch(`${l}/admin/realms/${d}/users?email=${encodeURIComponent(e)}`,{headers:{Authorization:`Bearer ${t}`}});if(!n.ok)throw new Error("Failed to get user");const o=await n.json();return o.length>0?o[0].id:null}catch(t){return a.error("Error getting user ID:",t),null}}(t,r);if(e){a.info("🚪 Logging out from Keycloak...");const n=await async function(t,e){try{const n=await fetch(`${l}/admin/realms/${d}/users/${e}/logout`,{method:"POST",headers:{Authorization:`Bearer ${t}`}});return n.ok||204===n.status}catch(t){return a.error("Error logging out user from Keycloak:",t),!1}}(t,e);n?a.info("✅ Keycloak sessions terminated"):a.info("⚠️ Failed to logout from Keycloak")}else a.info("⚠️ User not found in Keycloak")}else a.info("⚠️ Failed to get Keycloak admin token")}catch(t){a.error("⚠️ Error logging out from Keycloak: "+t.message)}a.info("🎉 Logout completed"),e.json({success:!0,message:"Logged out successfully from Directus and Keycloak"})}catch(t){a.error("❌ Error in logout:",t),e.status(500).json({error:t.message,message:"Failed to logout"})}}),t.post("/apple-token",async(t,n)=>{const{identityToken:o,firstName:l,lastName:d}=t.body;if(a.info("🍎 Apple token exchange request received"),!o)return n.status(400).json({error:"identityToken is required",message:"Apple identityToken must be provided in the request body"});try{const t="com.forumbandung.app",u=async n=>{const[o,r,i]=n.split("."),s=JSON.parse(Buffer.from(o,"base64").toString()),c=JSON.parse(Buffer.from(r,"base64").toString());if(a.info("🍎 Apple Token Payload: "+JSON.stringify(c)),"https://appleid.apple.com"!==c.iss)throw new Error("Invalid issuer");const l=[t.toLowerCase(),"host.exp.exponent"],d=c.aud.toLowerCase();if(!l.includes(d))throw a.error(`❌ Invalid audience: ${c.aud}. Expected one of: ${l.join(", ")}`),new Error("Invalid audience");if(c.exp<Math.floor(Date.now()/1e3))throw new Error("Token expired");const u=await fetch("https://appleid.apple.com/auth/keys"),{keys:p}=await u.json(),f=p.find(t=>t.kid===s.kid);if(!f)throw new Error("Apple public key not found");const g=e.createPublicKey({key:f,format:"jwk"}),h=e.createVerify("RSA-SHA256");h.update(`${o}.${r}`);if(!h.verify(g,i,"base64url"))throw new Error("Invalid signature");return c},p=await u(o),{email:f,sub:g}=p;if(!f)throw new Error("Apple token did not contain an email");a.info(`✅ Apple token verified for: ${f} (${g})`);const{UsersService:h,AuthenticationService:m}=i,y=await c(),k=new h({schema:y,knex:s}),b=await k.readByQuery({filter:{email:{_eq:f}}});let x,w;b.length>0?(w=b[0],x=w.id,a.info(`👤 Found existing user: ${x}`),w.external_identifier||await k.updateOne(x,{external_identifier:g,provider:"apple"})):(a.info(`📝 Creating new user for: ${f}`),x=await k.createOne({email:f,first_name:l||"Apple User",last_name:d||"",role:r.DEFAULT_ROLE_ID||"36010211-604f-4ce3-84d9-4e69d16781a1",status:"active",provider:"apple",external_identifier:g}),w=await k.readOne(x));new m({schema:y,knex:s});try{const t=await k.readOne(x,{fields:["*","token"]});let o=t.token;o||(a.info(`🔑 Generating new static token for user: ${x}`),o=e.randomBytes(32).toString("hex"),await k.updateOne(x,{token:o})),n.json({success:!0,data:{access_token:o,refresh_token:o,expires:604800,user:t},user_id:x,email:f,provider:"apple"})}catch(t){a.error("⚠️ Could not generate static token: "+t.message),n.status(500).json({error:"Session error",message:"Apple authentication verified but session generation failed."})}}catch(t){a.error("❌ Error in Apple token exchange:",t),n.status(500).json({error:t.message,message:"Failed to verify Apple token"})}}),t.get("/bridge",async(t,e)=>{const{token:n,redirect_uri:o,redirect:r}=t.query,i=n,s=o||r||"/";if(a.info("🌉 WebView Bridge request received"),!i)return e.status(400).json({error:"Token required",message:"No access token provided"});try{const t=await fetch(`${f}/users/me`,{headers:{Authorization:`Bearer ${i}`}});if(!t.ok)return a.error("❌ Bridge: Invalid token provided"),e.status(401).json({error:"Invalid token",message:"The provided token is invalid or expired"});const n=await t.json();return a.info(`✅ Bridge: Session established for ${n.data.email}`),e.cookie(w,i,{httpOnly:!0,secure:b,domain:k,sameSite:x,maxAge:6048e5,path:"/"}),w!==v&&e.cookie(v,i,{httpOnly:!0,secure:b,domain:k,sameSite:x,maxAge:6048e5,path:"/"}),a.info("🔄 Bridge: Redirecting to "+s),e.redirect(s)}catch(t){a.error("❌ Bridge error: "+t.message),e.status(500).json({error:"Bridge failure",message:t.message})}})}};export{r as default};
|
|
1
|
+
import{createRequire as t}from"module";import e from"node:crypto";import r from"buffer";import n from"stream";import o from"util";import i from"crypto";function s(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var a={},c={exports:{}};
|
|
2
|
+
/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
|
3
|
+
!function(t,e){var n=r,o=n.Buffer;function i(t,e){for(var r in t)e[r]=t[r]}function s(t,e,r){return o(t,e,r)}o.from&&o.alloc&&o.allocUnsafe&&o.allocUnsafeSlow?t.exports=n:(i(n,e),e.Buffer=s),s.prototype=Object.create(o.prototype),i(o,s),s.from=function(t,e,r){if("number"==typeof t)throw new TypeError("Argument must not be a number");return o(t,e,r)},s.alloc=function(t,e,r){if("number"!=typeof t)throw new TypeError("Argument must be a number");var n=o(t);return void 0!==e?"string"==typeof r?n.fill(e,r):n.fill(e):n.fill(0),n},s.allocUnsafe=function(t){if("number"!=typeof t)throw new TypeError("Argument must be a number");return o(t)},s.allocUnsafeSlow=function(t){if("number"!=typeof t)throw new TypeError("Argument must be a number");return n.SlowBuffer(t)}}(c,c.exports);var l=c.exports,u=l.Buffer,f=n;function p(t){if(this.buffer=null,this.writable=!0,this.readable=!0,!t)return this.buffer=u.alloc(0),this;if("function"==typeof t.pipe)return this.buffer=u.alloc(0),t.pipe(this),this;if(t.length||"object"==typeof t)return this.buffer=t,this.writable=!1,process.nextTick(function(){this.emit("end",t),this.readable=!1,this.emit("close")}.bind(this)),this;throw new TypeError("Unexpected data type ("+typeof t+")")}o.inherits(p,f),p.prototype.write=function(t){this.buffer=u.concat([this.buffer,u.from(t)]),this.emit("data",t)},p.prototype.end=function(t){t&&this.write(t),this.emit("end",t),this.emit("close"),this.writable=!1,this.readable=!1};var h=p;function d(t){return(t/8|0)+(t%8==0?0:1)}var m={ES256:d(256),ES384:d(384),ES512:d(521)};var g=function(t){var e=m[t];if(e)return e;throw new Error('Unknown algorithm "'+t+'"')},y=l.Buffer,E=g,v=128;function b(t){if(y.isBuffer(t))return t;if("string"==typeof t)return y.from(t,"base64");throw new TypeError("ECDSA signature must be a Base64 string or a Buffer")}function w(t,e,r){for(var n=0;e+n<r&&0===t[e+n];)++n;return t[e+n]>=v&&--n,n}var S,$,R={derToJose:function(t,e){t=b(t);var r=E(e),n=r+1,o=t.length,i=0;if(48!==t[i++])throw new Error('Could not find expected "seq"');var s=t[i++];if(129===s&&(s=t[i++]),o-i<s)throw new Error('"seq" specified length of "'+s+'", only "'+(o-i)+'" remaining');if(2!==t[i++])throw new Error('Could not find expected "int" for "r"');var a=t[i++];if(o-i-2<a)throw new Error('"r" specified length of "'+a+'", only "'+(o-i-2)+'" available');if(n<a)throw new Error('"r" specified length of "'+a+'", max of "'+n+'" is acceptable');var c=i;if(i+=a,2!==t[i++])throw new Error('Could not find expected "int" for "s"');var l=t[i++];if(o-i!==l)throw new Error('"s" specified length of "'+l+'", expected "'+(o-i)+'"');if(n<l)throw new Error('"s" specified length of "'+l+'", max of "'+n+'" is acceptable');var u=i;if((i+=l)!==o)throw new Error('Expected to consume entire buffer, but "'+(o-i)+'" bytes remain');var f=r-a,p=r-l,h=y.allocUnsafe(f+a+p+l);for(i=0;i<f;++i)h[i]=0;t.copy(h,i,c+Math.max(-f,0),c+a);for(var d=i=r;i<d+p;++i)h[i]=0;return t.copy(h,i,u+Math.max(-p,0),u+l),h=(h=h.toString("base64")).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")},joseToDer:function(t,e){t=b(t);var r=E(e),n=t.length;if(n!==2*r)throw new TypeError('"'+e+'" signatures must be "'+2*r+'" bytes, saw "'+n+'"');var o=w(t,0,r),i=w(t,r,t.length),s=r-o,a=r-i,c=2+s+1+1+a,l=c<v,u=y.allocUnsafe((l?2:3)+c),f=0;return u[f++]=48,l?u[f++]=c:(u[f++]=129,u[f++]=255&c),u[f++]=2,u[f++]=s,o<0?(u[f++]=0,f+=t.copy(u,f,0,r)):f+=t.copy(u,f,o,r),u[f++]=2,u[f++]=a,i<0?(u[f++]=0,t.copy(u,f,r)):t.copy(u,f,r+i),u}};var I,A=l.Buffer,O=i,k=R,L=o,T="secret must be a string or buffer",N="key must be a string or a buffer",x="function"==typeof O.createPublicKey;function P(t){if(!A.isBuffer(t)&&"string"!=typeof t){if(!x)throw D(N);if("object"!=typeof t)throw D(N);if("string"!=typeof t.type)throw D(N);if("string"!=typeof t.asymmetricKeyType)throw D(N);if("function"!=typeof t.export)throw D(N)}}function j(t){if(!A.isBuffer(t)&&"string"!=typeof t&&"object"!=typeof t)throw D("key must be a string, a buffer or an object")}function _(t){return t.replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}function C(t){var e=4-(t=t.toString()).length%4;if(4!==e)for(var r=0;r<e;++r)t+="=";return t.replace(/\-/g,"+").replace(/_/g,"/")}function D(t){var e=[].slice.call(arguments,1),r=L.format.bind(L,t).apply(null,e);return new TypeError(r)}function M(t){var e;return e=t,A.isBuffer(e)||"string"==typeof e||(t=JSON.stringify(t)),t}function B(t){return function(e,r){!function(t){if(!A.isBuffer(t)){if("string"==typeof t)return t;if(!x)throw D(T);if("object"!=typeof t)throw D(T);if("secret"!==t.type)throw D(T);if("function"!=typeof t.export)throw D(T)}}(r),e=M(e);var n=O.createHmac("sha"+t,r);return _((n.update(e),n.digest("base64")))}}x&&(N+=" or a KeyObject",T+="or a KeyObject");var F="timingSafeEqual"in O?function(t,e){return t.byteLength===e.byteLength&&O.timingSafeEqual(t,e)}:function(t,e){return I||(I=function(){if($)return S;$=1;var t=r.Buffer,e=r.SlowBuffer;function n(e,r){if(!t.isBuffer(e)||!t.isBuffer(r))return!1;if(e.length!==r.length)return!1;for(var n=0,o=0;o<e.length;o++)n|=e[o]^r[o];return 0===n}S=n,n.install=function(){t.prototype.equal=e.prototype.equal=function(t){return n(this,t)}};var o=t.prototype.equal,i=e.prototype.equal;return n.restore=function(){t.prototype.equal=o,e.prototype.equal=i},S}()),I(t,e)};function U(t){return function(e,r,n){var o=B(t)(e,n);return F(A.from(r),A.from(o))}}function K(t){return function(e,r){j(r),e=M(e);var n=O.createSign("RSA-SHA"+t);return _((n.update(e),n.sign(r,"base64")))}}function G(t){return function(e,r,n){P(n),e=M(e),r=C(r);var o=O.createVerify("RSA-SHA"+t);return o.update(e),o.verify(n,r,"base64")}}function q(t){return function(e,r){j(r),e=M(e);var n=O.createSign("RSA-SHA"+t);return _((n.update(e),n.sign({key:r,padding:O.constants.RSA_PKCS1_PSS_PADDING,saltLength:O.constants.RSA_PSS_SALTLEN_DIGEST},"base64")))}}function H(t){return function(e,r,n){P(n),e=M(e),r=C(r);var o=O.createVerify("RSA-SHA"+t);return o.update(e),o.verify({key:n,padding:O.constants.RSA_PKCS1_PSS_PADDING,saltLength:O.constants.RSA_PSS_SALTLEN_DIGEST},r,"base64")}}function V(t){var e=K(t);return function(){var r=e.apply(null,arguments);return r=k.derToJose(r,"ES"+t)}}function X(t){var e=G(t);return function(r,n,o){return n=k.joseToDer(n,"ES"+t).toString("base64"),e(r,n,o)}}function z(){return function(){return""}}function W(){return function(t,e){return""===e}}var J=function(t){var e={hs:B,rs:K,ps:q,es:V,none:z},r={hs:U,rs:G,ps:H,es:X,none:W},n=t.match(/^(RS|PS|ES|HS)(256|384|512)$|^(none)$/);if(!n)throw D('"%s" is not a valid algorithm.\n Supported algorithms are:\n "HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "PS256", "PS384", "PS512", "ES256", "ES384", "ES512" and "none".',t);var o=(n[1]||n[3]).toLowerCase(),i=n[2];return{sign:e[o](i),verify:r[o](i)}},Y=r.Buffer,Z=function(t){return"string"==typeof t?t:"number"==typeof t||Y.isBuffer(t)?t.toString():JSON.stringify(t)},Q=l.Buffer,tt=h,et=J,rt=n,nt=Z,ot=o;function it(t,e){return Q.from(t,e).toString("base64").replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}function st(t){var e=t.header,r=t.payload,n=t.secret||t.privateKey,o=t.encoding,i=et(e.alg),s=function(t,e,r){r=r||"utf8";var n=it(nt(t),"binary"),o=it(nt(e),r);return ot.format("%s.%s",n,o)}(e,r,o),a=i.sign(s,n);return ot.format("%s.%s",s,a)}function at(t){var e=t.secret;if(e=null==(e=null==e?t.privateKey:e)?t.key:e,!0===/^hs/i.test(t.header.alg)&&null==e)throw new TypeError("secret must be a string or buffer or a KeyObject");var r=new tt(e);this.readable=!0,this.header=t.header,this.encoding=t.encoding,this.secret=this.privateKey=this.key=r,this.payload=new tt(t.payload),this.secret.once("close",function(){!this.payload.writable&&this.readable&&this.sign()}.bind(this)),this.payload.once("close",function(){!this.secret.writable&&this.readable&&this.sign()}.bind(this))}ot.inherits(at,rt),at.prototype.sign=function(){try{var t=st({header:this.header,payload:this.payload.buffer,secret:this.secret.buffer,encoding:this.encoding});return this.emit("done",t),this.emit("data",t),this.emit("end"),this.readable=!1,t}catch(t){this.readable=!1,this.emit("error",t),this.emit("close")}},at.sign=st;var ct=at,lt=l.Buffer,ut=h,ft=J,pt=n,ht=Z,dt=/^[a-zA-Z0-9\-_]+?\.[a-zA-Z0-9\-_]+?\.([a-zA-Z0-9\-_]+)?$/;function mt(t){if(function(t){return"[object Object]"===Object.prototype.toString.call(t)}(t))return t;try{return JSON.parse(t)}catch(t){return}}function gt(t){var e=t.split(".",1)[0];return mt(lt.from(e,"base64").toString("binary"))}function yt(t){return t.split(".")[2]}function Et(t){return dt.test(t)&&!!gt(t)}function vt(t,e,r){if(!e){var n=new Error("Missing algorithm parameter for jws.verify");throw n.code="MISSING_ALGORITHM",n}var o=yt(t=ht(t)),i=function(t){return t.split(".",2).join(".")}(t);return ft(e).verify(i,o,r)}function bt(t,e){if(e=e||{},!Et(t=ht(t)))return null;var r=gt(t);if(!r)return null;var n=function(t,e){e=e||"utf8";var r=t.split(".")[1];return lt.from(r,"base64").toString(e)}(t);return("JWT"===r.typ||e.json)&&(n=JSON.parse(n,e.encoding)),{header:r,payload:n,signature:yt(t)}}function wt(t){var e=(t=t||{}).secret;if(e=null==(e=null==e?t.publicKey:e)?t.key:e,!0===/^hs/i.test(t.algorithm)&&null==e)throw new TypeError("secret must be a string or buffer or a KeyObject");var r=new ut(e);this.readable=!0,this.algorithm=t.algorithm,this.encoding=t.encoding,this.secret=this.publicKey=this.key=r,this.signature=new ut(t.signature),this.secret.once("close",function(){!this.signature.writable&&this.readable&&this.verify()}.bind(this)),this.signature.once("close",function(){!this.secret.writable&&this.readable&&this.verify()}.bind(this))}o.inherits(wt,pt),wt.prototype.verify=function(){try{var t=vt(this.signature.buffer,this.algorithm,this.key.buffer),e=bt(this.signature.buffer,this.encoding);return this.emit("done",t,e),this.emit("data",t),this.emit("end"),this.readable=!1,t}catch(t){this.readable=!1,this.emit("error",t),this.emit("close")}},wt.decode=bt,wt.isValid=Et,wt.verify=vt;var St=ct,$t=wt;a.ALGORITHMS=["HS256","HS384","HS512","RS256","RS384","RS512","PS256","PS384","PS512","ES256","ES384","ES512"],a.sign=St.sign,a.verify=$t.verify,a.decode=$t.decode,a.isValid=$t.isValid,a.createSign=function(t){return new St(t)},a.createVerify=function(t){return new $t(t)};var Rt=a,It=function(t,e){e=e||{};var r=Rt.decode(t,e);if(!r)return null;var n=r.payload;if("string"==typeof n)try{var o=JSON.parse(n);null!==o&&"object"==typeof o&&(n=o)}catch(t){}return!0===e.complete?{header:r.header,payload:n,signature:r.signature}:n},At=function(t,e){Error.call(this,t),Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),this.name="JsonWebTokenError",this.message=t,e&&(this.inner=e)};(At.prototype=Object.create(Error.prototype)).constructor=At;var Ot=At,kt=Ot,Lt=function(t,e){kt.call(this,t),this.name="NotBeforeError",this.date=e};(Lt.prototype=Object.create(kt.prototype)).constructor=Lt;var Tt=Lt,Nt=Ot,xt=function(t,e){Nt.call(this,t),this.name="TokenExpiredError",this.expiredAt=e};(xt.prototype=Object.create(Nt.prototype)).constructor=xt;var Pt=xt,jt=1e3,_t=60*jt,Ct=60*_t,Dt=24*Ct,Mt=7*Dt,Bt=365.25*Dt;function Ft(t,e,r,n){var o=e>=1.5*r;return Math.round(t/r)+" "+n+(o?"s":"")}var Ut=function(t,e){e=e||{};var r=typeof t;if("string"===r&&t.length>0)return function(t){if((t=String(t)).length>100)return;var e=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(t);if(!e)return;var r=parseFloat(e[1]);switch((e[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return r*Bt;case"weeks":case"week":case"w":return r*Mt;case"days":case"day":case"d":return r*Dt;case"hours":case"hour":case"hrs":case"hr":case"h":return r*Ct;case"minutes":case"minute":case"mins":case"min":case"m":return r*_t;case"seconds":case"second":case"secs":case"sec":case"s":return r*jt;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return r;default:return}}(t);if("number"===r&&isFinite(t))return e.long?function(t){var e=Math.abs(t);if(e>=Dt)return Ft(t,e,Dt,"day");if(e>=Ct)return Ft(t,e,Ct,"hour");if(e>=_t)return Ft(t,e,_t,"minute");if(e>=jt)return Ft(t,e,jt,"second");return t+" ms"}(t):function(t){var e=Math.abs(t);if(e>=Dt)return Math.round(t/Dt)+"d";if(e>=Ct)return Math.round(t/Ct)+"h";if(e>=_t)return Math.round(t/_t)+"m";if(e>=jt)return Math.round(t/jt)+"s";return t+"ms"}(t);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(t))},Kt=function(t,e){var r=e||Math.floor(Date.now()/1e3);if("string"==typeof t){var n=Ut(t);if(void 0===n)return;return Math.floor(r+n/1e3)}return"number"==typeof t?r+t:void 0},Gt={exports:{}};var qt={MAX_LENGTH:256,MAX_SAFE_COMPONENT_LENGTH:16,MAX_SAFE_BUILD_LENGTH:250,MAX_SAFE_INTEGER:Number.MAX_SAFE_INTEGER||9007199254740991,RELEASE_TYPES:["major","premajor","minor","preminor","patch","prepatch","prerelease"],SEMVER_SPEC_VERSION:"2.0.0",FLAG_INCLUDE_PRERELEASE:1,FLAG_LOOSE:2};var Ht="object"==typeof process&&process.env&&process.env.NODE_DEBUG&&/\bsemver\b/i.test(process.env.NODE_DEBUG)?(...t)=>console.error("SEMVER",...t):()=>{};!function(t,e){const{MAX_SAFE_COMPONENT_LENGTH:r,MAX_SAFE_BUILD_LENGTH:n,MAX_LENGTH:o}=qt,i=Ht,s=(e=t.exports={}).re=[],a=e.safeRe=[],c=e.src=[],l=e.safeSrc=[],u=e.t={};let f=0;const p="[a-zA-Z0-9-]",h=[["\\s",1],["\\d",o],[p,n]],d=(t,e,r)=>{const n=(t=>{for(const[e,r]of h)t=t.split(`${e}*`).join(`${e}{0,${r}}`).split(`${e}+`).join(`${e}{1,${r}}`);return t})(e),o=f++;i(t,o,e),u[t]=o,c[o]=e,l[o]=n,s[o]=new RegExp(e,r?"g":void 0),a[o]=new RegExp(n,r?"g":void 0)};d("NUMERICIDENTIFIER","0|[1-9]\\d*"),d("NUMERICIDENTIFIERLOOSE","\\d+"),d("NONNUMERICIDENTIFIER",`\\d*[a-zA-Z-]${p}*`),d("MAINVERSION",`(${c[u.NUMERICIDENTIFIER]})\\.(${c[u.NUMERICIDENTIFIER]})\\.(${c[u.NUMERICIDENTIFIER]})`),d("MAINVERSIONLOOSE",`(${c[u.NUMERICIDENTIFIERLOOSE]})\\.(${c[u.NUMERICIDENTIFIERLOOSE]})\\.(${c[u.NUMERICIDENTIFIERLOOSE]})`),d("PRERELEASEIDENTIFIER",`(?:${c[u.NONNUMERICIDENTIFIER]}|${c[u.NUMERICIDENTIFIER]})`),d("PRERELEASEIDENTIFIERLOOSE",`(?:${c[u.NONNUMERICIDENTIFIER]}|${c[u.NUMERICIDENTIFIERLOOSE]})`),d("PRERELEASE",`(?:-(${c[u.PRERELEASEIDENTIFIER]}(?:\\.${c[u.PRERELEASEIDENTIFIER]})*))`),d("PRERELEASELOOSE",`(?:-?(${c[u.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${c[u.PRERELEASEIDENTIFIERLOOSE]})*))`),d("BUILDIDENTIFIER",`${p}+`),d("BUILD",`(?:\\+(${c[u.BUILDIDENTIFIER]}(?:\\.${c[u.BUILDIDENTIFIER]})*))`),d("FULLPLAIN",`v?${c[u.MAINVERSION]}${c[u.PRERELEASE]}?${c[u.BUILD]}?`),d("FULL",`^${c[u.FULLPLAIN]}$`),d("LOOSEPLAIN",`[v=\\s]*${c[u.MAINVERSIONLOOSE]}${c[u.PRERELEASELOOSE]}?${c[u.BUILD]}?`),d("LOOSE",`^${c[u.LOOSEPLAIN]}$`),d("GTLT","((?:<|>)?=?)"),d("XRANGEIDENTIFIERLOOSE",`${c[u.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`),d("XRANGEIDENTIFIER",`${c[u.NUMERICIDENTIFIER]}|x|X|\\*`),d("XRANGEPLAIN",`[v=\\s]*(${c[u.XRANGEIDENTIFIER]})(?:\\.(${c[u.XRANGEIDENTIFIER]})(?:\\.(${c[u.XRANGEIDENTIFIER]})(?:${c[u.PRERELEASE]})?${c[u.BUILD]}?)?)?`),d("XRANGEPLAINLOOSE",`[v=\\s]*(${c[u.XRANGEIDENTIFIERLOOSE]})(?:\\.(${c[u.XRANGEIDENTIFIERLOOSE]})(?:\\.(${c[u.XRANGEIDENTIFIERLOOSE]})(?:${c[u.PRERELEASELOOSE]})?${c[u.BUILD]}?)?)?`),d("XRANGE",`^${c[u.GTLT]}\\s*${c[u.XRANGEPLAIN]}$`),d("XRANGELOOSE",`^${c[u.GTLT]}\\s*${c[u.XRANGEPLAINLOOSE]}$`),d("COERCEPLAIN",`(^|[^\\d])(\\d{1,${r}})(?:\\.(\\d{1,${r}}))?(?:\\.(\\d{1,${r}}))?`),d("COERCE",`${c[u.COERCEPLAIN]}(?:$|[^\\d])`),d("COERCEFULL",c[u.COERCEPLAIN]+`(?:${c[u.PRERELEASE]})?`+`(?:${c[u.BUILD]})?(?:$|[^\\d])`),d("COERCERTL",c[u.COERCE],!0),d("COERCERTLFULL",c[u.COERCEFULL],!0),d("LONETILDE","(?:~>?)"),d("TILDETRIM",`(\\s*)${c[u.LONETILDE]}\\s+`,!0),e.tildeTrimReplace="$1~",d("TILDE",`^${c[u.LONETILDE]}${c[u.XRANGEPLAIN]}$`),d("TILDELOOSE",`^${c[u.LONETILDE]}${c[u.XRANGEPLAINLOOSE]}$`),d("LONECARET","(?:\\^)"),d("CARETTRIM",`(\\s*)${c[u.LONECARET]}\\s+`,!0),e.caretTrimReplace="$1^",d("CARET",`^${c[u.LONECARET]}${c[u.XRANGEPLAIN]}$`),d("CARETLOOSE",`^${c[u.LONECARET]}${c[u.XRANGEPLAINLOOSE]}$`),d("COMPARATORLOOSE",`^${c[u.GTLT]}\\s*(${c[u.LOOSEPLAIN]})$|^$`),d("COMPARATOR",`^${c[u.GTLT]}\\s*(${c[u.FULLPLAIN]})$|^$`),d("COMPARATORTRIM",`(\\s*)${c[u.GTLT]}\\s*(${c[u.LOOSEPLAIN]}|${c[u.XRANGEPLAIN]})`,!0),e.comparatorTrimReplace="$1$2$3",d("HYPHENRANGE",`^\\s*(${c[u.XRANGEPLAIN]})\\s+-\\s+(${c[u.XRANGEPLAIN]})\\s*$`),d("HYPHENRANGELOOSE",`^\\s*(${c[u.XRANGEPLAINLOOSE]})\\s+-\\s+(${c[u.XRANGEPLAINLOOSE]})\\s*$`),d("STAR","(<|>)?=?\\s*\\*"),d("GTE0","^\\s*>=\\s*0\\.0\\.0\\s*$"),d("GTE0PRE","^\\s*>=\\s*0\\.0\\.0-0\\s*$")}(Gt,Gt.exports);var Vt=Gt.exports;const Xt=Object.freeze({loose:!0}),zt=Object.freeze({});var Wt=t=>t?"object"!=typeof t?Xt:t:zt;const Jt=/^[0-9]+$/,Yt=(t,e)=>{if("number"==typeof t&&"number"==typeof e)return t===e?0:t<e?-1:1;const r=Jt.test(t),n=Jt.test(e);return r&&n&&(t=+t,e=+e),t===e?0:r&&!n?-1:n&&!r?1:t<e?-1:1};var Zt={compareIdentifiers:Yt,rcompareIdentifiers:(t,e)=>Yt(e,t)};const Qt=Ht,{MAX_LENGTH:te,MAX_SAFE_INTEGER:ee}=qt,{safeRe:re,t:ne}=Vt,oe=Wt,{compareIdentifiers:ie}=Zt;var se=class t{constructor(e,r){if(r=oe(r),e instanceof t){if(e.loose===!!r.loose&&e.includePrerelease===!!r.includePrerelease)return e;e=e.version}else if("string"!=typeof e)throw new TypeError(`Invalid version. Must be a string. Got type "${typeof e}".`);if(e.length>te)throw new TypeError(`version is longer than ${te} characters`);Qt("SemVer",e,r),this.options=r,this.loose=!!r.loose,this.includePrerelease=!!r.includePrerelease;const n=e.trim().match(r.loose?re[ne.LOOSE]:re[ne.FULL]);if(!n)throw new TypeError(`Invalid Version: ${e}`);if(this.raw=e,this.major=+n[1],this.minor=+n[2],this.patch=+n[3],this.major>ee||this.major<0)throw new TypeError("Invalid major version");if(this.minor>ee||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>ee||this.patch<0)throw new TypeError("Invalid patch version");n[4]?this.prerelease=n[4].split(".").map(t=>{if(/^[0-9]+$/.test(t)){const e=+t;if(e>=0&&e<ee)return e}return t}):this.prerelease=[],this.build=n[5]?n[5].split("."):[],this.format()}format(){return this.version=`${this.major}.${this.minor}.${this.patch}`,this.prerelease.length&&(this.version+=`-${this.prerelease.join(".")}`),this.version}toString(){return this.version}compare(e){if(Qt("SemVer.compare",this.version,this.options,e),!(e instanceof t)){if("string"==typeof e&&e===this.version)return 0;e=new t(e,this.options)}return e.version===this.version?0:this.compareMain(e)||this.comparePre(e)}compareMain(e){return e instanceof t||(e=new t(e,this.options)),this.major<e.major?-1:this.major>e.major?1:this.minor<e.minor?-1:this.minor>e.minor?1:this.patch<e.patch?-1:this.patch>e.patch?1:0}comparePre(e){if(e instanceof t||(e=new t(e,this.options)),this.prerelease.length&&!e.prerelease.length)return-1;if(!this.prerelease.length&&e.prerelease.length)return 1;if(!this.prerelease.length&&!e.prerelease.length)return 0;let r=0;do{const t=this.prerelease[r],n=e.prerelease[r];if(Qt("prerelease compare",r,t,n),void 0===t&&void 0===n)return 0;if(void 0===n)return 1;if(void 0===t)return-1;if(t!==n)return ie(t,n)}while(++r)}compareBuild(e){e instanceof t||(e=new t(e,this.options));let r=0;do{const t=this.build[r],n=e.build[r];if(Qt("build compare",r,t,n),void 0===t&&void 0===n)return 0;if(void 0===n)return 1;if(void 0===t)return-1;if(t!==n)return ie(t,n)}while(++r)}inc(t,e,r){if(t.startsWith("pre")){if(!e&&!1===r)throw new Error("invalid increment argument: identifier is empty");if(e){const t=`-${e}`.match(this.options.loose?re[ne.PRERELEASELOOSE]:re[ne.PRERELEASE]);if(!t||t[1]!==e)throw new Error(`invalid identifier: ${e}`)}}switch(t){case"premajor":this.prerelease.length=0,this.patch=0,this.minor=0,this.major++,this.inc("pre",e,r);break;case"preminor":this.prerelease.length=0,this.patch=0,this.minor++,this.inc("pre",e,r);break;case"prepatch":this.prerelease.length=0,this.inc("patch",e,r),this.inc("pre",e,r);break;case"prerelease":0===this.prerelease.length&&this.inc("patch",e,r),this.inc("pre",e,r);break;case"release":if(0===this.prerelease.length)throw new Error(`version ${this.raw} is not a prerelease`);this.prerelease.length=0;break;case"major":0===this.minor&&0===this.patch&&0!==this.prerelease.length||this.major++,this.minor=0,this.patch=0,this.prerelease=[];break;case"minor":0===this.patch&&0!==this.prerelease.length||this.minor++,this.patch=0,this.prerelease=[];break;case"patch":0===this.prerelease.length&&this.patch++,this.prerelease=[];break;case"pre":{const t=Number(r)?1:0;if(0===this.prerelease.length)this.prerelease=[t];else{let n=this.prerelease.length;for(;--n>=0;)"number"==typeof this.prerelease[n]&&(this.prerelease[n]++,n=-2);if(-1===n){if(e===this.prerelease.join(".")&&!1===r)throw new Error("invalid increment argument: identifier already exists");this.prerelease.push(t)}}if(e){let n=[e,t];!1===r&&(n=[e]),0===ie(this.prerelease[0],e)?isNaN(this.prerelease[1])&&(this.prerelease=n):this.prerelease=n}break}default:throw new Error(`invalid increment argument: ${t}`)}return this.raw=this.format(),this.build.length&&(this.raw+=`+${this.build.join(".")}`),this}};const ae=se;var ce=(t,e,r=!1)=>{if(t instanceof ae)return t;try{return new ae(t,e)}catch(t){if(!r)return null;throw t}};const le=ce;var ue=(t,e)=>{const r=le(t,e);return r?r.version:null};const fe=ce;var pe=(t,e)=>{const r=fe(t.trim().replace(/^[=v]+/,""),e);return r?r.version:null};const he=se;var de=(t,e,r,n,o)=>{"string"==typeof r&&(o=n,n=r,r=void 0);try{return new he(t instanceof he?t.version:t,r).inc(e,n,o).version}catch(t){return null}};const me=ce;var ge=(t,e)=>{const r=me(t,null,!0),n=me(e,null,!0),o=r.compare(n);if(0===o)return null;const i=o>0,s=i?r:n,a=i?n:r,c=!!s.prerelease.length;if(!!a.prerelease.length&&!c){if(!a.patch&&!a.minor)return"major";if(0===a.compareMain(s))return a.minor&&!a.patch?"minor":"patch"}const l=c?"pre":"";return r.major!==n.major?l+"major":r.minor!==n.minor?l+"minor":r.patch!==n.patch?l+"patch":"prerelease"};const ye=se;var Ee=(t,e)=>new ye(t,e).major;const ve=se;var be=(t,e)=>new ve(t,e).minor;const we=se;var Se=(t,e)=>new we(t,e).patch;const $e=ce;var Re=(t,e)=>{const r=$e(t,e);return r&&r.prerelease.length?r.prerelease:null};const Ie=se;var Ae=(t,e,r)=>new Ie(t,r).compare(new Ie(e,r));const Oe=Ae;var ke=(t,e,r)=>Oe(e,t,r);const Le=Ae;var Te=(t,e)=>Le(t,e,!0);const Ne=se;var xe=(t,e,r)=>{const n=new Ne(t,r),o=new Ne(e,r);return n.compare(o)||n.compareBuild(o)};const Pe=xe;var je=(t,e)=>t.sort((t,r)=>Pe(t,r,e));const _e=xe;var Ce=(t,e)=>t.sort((t,r)=>_e(r,t,e));const De=Ae;var Me=(t,e,r)=>De(t,e,r)>0;const Be=Ae;var Fe=(t,e,r)=>Be(t,e,r)<0;const Ue=Ae;var Ke=(t,e,r)=>0===Ue(t,e,r);const Ge=Ae;var qe=(t,e,r)=>0!==Ge(t,e,r);const He=Ae;var Ve=(t,e,r)=>He(t,e,r)>=0;const Xe=Ae;var ze=(t,e,r)=>Xe(t,e,r)<=0;const We=Ke,Je=qe,Ye=Me,Ze=Ve,Qe=Fe,tr=ze;var er=(t,e,r,n)=>{switch(e){case"===":return"object"==typeof t&&(t=t.version),"object"==typeof r&&(r=r.version),t===r;case"!==":return"object"==typeof t&&(t=t.version),"object"==typeof r&&(r=r.version),t!==r;case"":case"=":case"==":return We(t,r,n);case"!=":return Je(t,r,n);case">":return Ye(t,r,n);case">=":return Ze(t,r,n);case"<":return Qe(t,r,n);case"<=":return tr(t,r,n);default:throw new TypeError(`Invalid operator: ${e}`)}};const rr=se,nr=ce,{safeRe:or,t:ir}=Vt;var sr=(t,e)=>{if(t instanceof rr)return t;if("number"==typeof t&&(t=String(t)),"string"!=typeof t)return null;let r=null;if((e=e||{}).rtl){const n=e.includePrerelease?or[ir.COERCERTLFULL]:or[ir.COERCERTL];let o;for(;(o=n.exec(t))&&(!r||r.index+r[0].length!==t.length);)r&&o.index+o[0].length===r.index+r[0].length||(r=o),n.lastIndex=o.index+o[1].length+o[2].length;n.lastIndex=-1}else r=t.match(e.includePrerelease?or[ir.COERCEFULL]:or[ir.COERCE]);if(null===r)return null;const n=r[2],o=r[3]||"0",i=r[4]||"0",s=e.includePrerelease&&r[5]?`-${r[5]}`:"",a=e.includePrerelease&&r[6]?`+${r[6]}`:"";return nr(`${n}.${o}.${i}${s}${a}`,e)};var ar,cr,lr,ur,fr=class{constructor(){this.max=1e3,this.map=new Map}get(t){const e=this.map.get(t);return void 0===e?void 0:(this.map.delete(t),this.map.set(t,e),e)}delete(t){return this.map.delete(t)}set(t,e){if(!this.delete(t)&&void 0!==e){if(this.map.size>=this.max){const t=this.map.keys().next().value;this.delete(t)}this.map.set(t,e)}return this}};function pr(){if(cr)return ar;cr=1;const t=/\s+/g;class e{constructor(r,i){if(i=n(i),r instanceof e)return r.loose===!!i.loose&&r.includePrerelease===!!i.includePrerelease?r:new e(r.raw,i);if(r instanceof o)return this.raw=r.value,this.set=[[r]],this.formatted=void 0,this;if(this.options=i,this.loose=!!i.loose,this.includePrerelease=!!i.includePrerelease,this.raw=r.trim().replace(t," "),this.set=this.raw.split("||").map(t=>this.parseRange(t.trim())).filter(t=>t.length),!this.set.length)throw new TypeError(`Invalid SemVer Range: ${this.raw}`);if(this.set.length>1){const t=this.set[0];if(this.set=this.set.filter(t=>!d(t[0])),0===this.set.length)this.set=[t];else if(this.set.length>1)for(const t of this.set)if(1===t.length&&m(t[0])){this.set=[t];break}}this.formatted=void 0}get range(){if(void 0===this.formatted){this.formatted="";for(let t=0;t<this.set.length;t++){t>0&&(this.formatted+="||");const e=this.set[t];for(let t=0;t<e.length;t++)t>0&&(this.formatted+=" "),this.formatted+=e[t].toString().trim()}}return this.formatted}format(){return this.range}toString(){return this.range}parseRange(t){const e=((this.options.includePrerelease&&p)|(this.options.loose&&h))+":"+t,n=r.get(e);if(n)return n;const s=this.options.loose,m=s?a[c.HYPHENRANGELOOSE]:a[c.HYPHENRANGE];t=t.replace(m,O(this.options.includePrerelease)),i("hyphen replace",t),t=t.replace(a[c.COMPARATORTRIM],l),i("comparator trim",t),t=t.replace(a[c.TILDETRIM],u),i("tilde trim",t),t=t.replace(a[c.CARETTRIM],f),i("caret trim",t);let g=t.split(" ").map(t=>y(t,this.options)).join(" ").split(/\s+/).map(t=>A(t,this.options));s&&(g=g.filter(t=>(i("loose invalid filter",t,this.options),!!t.match(a[c.COMPARATORLOOSE])))),i("range list",g);const E=new Map,v=g.map(t=>new o(t,this.options));for(const t of v){if(d(t))return[t];E.set(t.value,t)}E.size>1&&E.has("")&&E.delete("");const b=[...E.values()];return r.set(e,b),b}intersects(t,r){if(!(t instanceof e))throw new TypeError("a Range is required");return this.set.some(e=>g(e,r)&&t.set.some(t=>g(t,r)&&e.every(e=>t.every(t=>e.intersects(t,r)))))}test(t){if(!t)return!1;if("string"==typeof t)try{t=new s(t,this.options)}catch(t){return!1}for(let e=0;e<this.set.length;e++)if(k(this.set[e],t,this.options))return!0;return!1}}ar=e;const r=new fr,n=Wt,o=hr(),i=Ht,s=se,{safeRe:a,t:c,comparatorTrimReplace:l,tildeTrimReplace:u,caretTrimReplace:f}=Vt,{FLAG_INCLUDE_PRERELEASE:p,FLAG_LOOSE:h}=qt,d=t=>"<0.0.0-0"===t.value,m=t=>""===t.value,g=(t,e)=>{let r=!0;const n=t.slice();let o=n.pop();for(;r&&n.length;)r=n.every(t=>o.intersects(t,e)),o=n.pop();return r},y=(t,e)=>(t=t.replace(a[c.BUILD],""),i("comp",t,e),t=w(t,e),i("caret",t),t=v(t,e),i("tildes",t),t=$(t,e),i("xrange",t),t=I(t,e),i("stars",t),t),E=t=>!t||"x"===t.toLowerCase()||"*"===t,v=(t,e)=>t.trim().split(/\s+/).map(t=>b(t,e)).join(" "),b=(t,e)=>{const r=e.loose?a[c.TILDELOOSE]:a[c.TILDE];return t.replace(r,(e,r,n,o,s)=>{let a;return i("tilde",t,e,r,n,o,s),E(r)?a="":E(n)?a=`>=${r}.0.0 <${+r+1}.0.0-0`:E(o)?a=`>=${r}.${n}.0 <${r}.${+n+1}.0-0`:s?(i("replaceTilde pr",s),a=`>=${r}.${n}.${o}-${s} <${r}.${+n+1}.0-0`):a=`>=${r}.${n}.${o} <${r}.${+n+1}.0-0`,i("tilde return",a),a})},w=(t,e)=>t.trim().split(/\s+/).map(t=>S(t,e)).join(" "),S=(t,e)=>{i("caret",t,e);const r=e.loose?a[c.CARETLOOSE]:a[c.CARET],n=e.includePrerelease?"-0":"";return t.replace(r,(e,r,o,s,a)=>{let c;return i("caret",t,e,r,o,s,a),E(r)?c="":E(o)?c=`>=${r}.0.0${n} <${+r+1}.0.0-0`:E(s)?c="0"===r?`>=${r}.${o}.0${n} <${r}.${+o+1}.0-0`:`>=${r}.${o}.0${n} <${+r+1}.0.0-0`:a?(i("replaceCaret pr",a),c="0"===r?"0"===o?`>=${r}.${o}.${s}-${a} <${r}.${o}.${+s+1}-0`:`>=${r}.${o}.${s}-${a} <${r}.${+o+1}.0-0`:`>=${r}.${o}.${s}-${a} <${+r+1}.0.0-0`):(i("no pr"),c="0"===r?"0"===o?`>=${r}.${o}.${s}${n} <${r}.${o}.${+s+1}-0`:`>=${r}.${o}.${s}${n} <${r}.${+o+1}.0-0`:`>=${r}.${o}.${s} <${+r+1}.0.0-0`),i("caret return",c),c})},$=(t,e)=>(i("replaceXRanges",t,e),t.split(/\s+/).map(t=>R(t,e)).join(" ")),R=(t,e)=>{t=t.trim();const r=e.loose?a[c.XRANGELOOSE]:a[c.XRANGE];return t.replace(r,(r,n,o,s,a,c)=>{i("xRange",t,r,n,o,s,a,c);const l=E(o),u=l||E(s),f=u||E(a),p=f;return"="===n&&p&&(n=""),c=e.includePrerelease?"-0":"",l?r=">"===n||"<"===n?"<0.0.0-0":"*":n&&p?(u&&(s=0),a=0,">"===n?(n=">=",u?(o=+o+1,s=0,a=0):(s=+s+1,a=0)):"<="===n&&(n="<",u?o=+o+1:s=+s+1),"<"===n&&(c="-0"),r=`${n+o}.${s}.${a}${c}`):u?r=`>=${o}.0.0${c} <${+o+1}.0.0-0`:f&&(r=`>=${o}.${s}.0${c} <${o}.${+s+1}.0-0`),i("xRange return",r),r})},I=(t,e)=>(i("replaceStars",t,e),t.trim().replace(a[c.STAR],"")),A=(t,e)=>(i("replaceGTE0",t,e),t.trim().replace(a[e.includePrerelease?c.GTE0PRE:c.GTE0],"")),O=t=>(e,r,n,o,i,s,a,c,l,u,f,p)=>`${r=E(n)?"":E(o)?`>=${n}.0.0${t?"-0":""}`:E(i)?`>=${n}.${o}.0${t?"-0":""}`:s?`>=${r}`:`>=${r}${t?"-0":""}`} ${c=E(l)?"":E(u)?`<${+l+1}.0.0-0`:E(f)?`<${l}.${+u+1}.0-0`:p?`<=${l}.${u}.${f}-${p}`:t?`<${l}.${u}.${+f+1}-0`:`<=${c}`}`.trim(),k=(t,e,r)=>{for(let r=0;r<t.length;r++)if(!t[r].test(e))return!1;if(e.prerelease.length&&!r.includePrerelease){for(let r=0;r<t.length;r++)if(i(t[r].semver),t[r].semver!==o.ANY&&t[r].semver.prerelease.length>0){const n=t[r].semver;if(n.major===e.major&&n.minor===e.minor&&n.patch===e.patch)return!0}return!1}return!0};return ar}function hr(){if(ur)return lr;ur=1;const t=Symbol("SemVer ANY");class e{static get ANY(){return t}constructor(n,o){if(o=r(o),n instanceof e){if(n.loose===!!o.loose)return n;n=n.value}n=n.trim().split(/\s+/).join(" "),s("comparator",n,o),this.options=o,this.loose=!!o.loose,this.parse(n),this.semver===t?this.value="":this.value=this.operator+this.semver.version,s("comp",this)}parse(e){const r=this.options.loose?n[o.COMPARATORLOOSE]:n[o.COMPARATOR],i=e.match(r);if(!i)throw new TypeError(`Invalid comparator: ${e}`);this.operator=void 0!==i[1]?i[1]:"","="===this.operator&&(this.operator=""),i[2]?this.semver=new a(i[2],this.options.loose):this.semver=t}toString(){return this.value}test(e){if(s("Comparator.test",e,this.options.loose),this.semver===t||e===t)return!0;if("string"==typeof e)try{e=new a(e,this.options)}catch(t){return!1}return i(e,this.operator,this.semver,this.options)}intersects(t,n){if(!(t instanceof e))throw new TypeError("a Comparator is required");return""===this.operator?""===this.value||new c(t.value,n).test(this.value):""===t.operator?""===t.value||new c(this.value,n).test(t.semver):(!(n=r(n)).includePrerelease||"<0.0.0-0"!==this.value&&"<0.0.0-0"!==t.value)&&(!(!n.includePrerelease&&(this.value.startsWith("<0.0.0")||t.value.startsWith("<0.0.0")))&&(!(!this.operator.startsWith(">")||!t.operator.startsWith(">"))||(!(!this.operator.startsWith("<")||!t.operator.startsWith("<"))||(!(this.semver.version!==t.semver.version||!this.operator.includes("=")||!t.operator.includes("="))||(!!(i(this.semver,"<",t.semver,n)&&this.operator.startsWith(">")&&t.operator.startsWith("<"))||!!(i(this.semver,">",t.semver,n)&&this.operator.startsWith("<")&&t.operator.startsWith(">")))))))}}lr=e;const r=Wt,{safeRe:n,t:o}=Vt,i=er,s=Ht,a=se,c=pr();return lr}const dr=pr();var mr=(t,e,r)=>{try{e=new dr(e,r)}catch(t){return!1}return e.test(t)};const gr=pr();var yr=(t,e)=>new gr(t,e).set.map(t=>t.map(t=>t.value).join(" ").trim().split(" "));const Er=se,vr=pr();var br=(t,e,r)=>{let n=null,o=null,i=null;try{i=new vr(e,r)}catch(t){return null}return t.forEach(t=>{i.test(t)&&(n&&-1!==o.compare(t)||(n=t,o=new Er(n,r)))}),n};const wr=se,Sr=pr();var $r=(t,e,r)=>{let n=null,o=null,i=null;try{i=new Sr(e,r)}catch(t){return null}return t.forEach(t=>{i.test(t)&&(n&&1!==o.compare(t)||(n=t,o=new wr(n,r)))}),n};const Rr=se,Ir=pr(),Ar=Me;var Or=(t,e)=>{t=new Ir(t,e);let r=new Rr("0.0.0");if(t.test(r))return r;if(r=new Rr("0.0.0-0"),t.test(r))return r;r=null;for(let e=0;e<t.set.length;++e){const n=t.set[e];let o=null;n.forEach(t=>{const e=new Rr(t.semver.version);switch(t.operator){case">":0===e.prerelease.length?e.patch++:e.prerelease.push(0),e.raw=e.format();case"":case">=":o&&!Ar(e,o)||(o=e);break;case"<":case"<=":break;default:throw new Error(`Unexpected operation: ${t.operator}`)}}),!o||r&&!Ar(r,o)||(r=o)}return r&&t.test(r)?r:null};const kr=pr();var Lr=(t,e)=>{try{return new kr(t,e).range||"*"}catch(t){return null}};const Tr=se,Nr=hr(),{ANY:xr}=Nr,Pr=pr(),jr=mr,_r=Me,Cr=Fe,Dr=ze,Mr=Ve;var Br=(t,e,r,n)=>{let o,i,s,a,c;switch(t=new Tr(t,n),e=new Pr(e,n),r){case">":o=_r,i=Dr,s=Cr,a=">",c=">=";break;case"<":o=Cr,i=Mr,s=_r,a="<",c="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(jr(t,e,n))return!1;for(let r=0;r<e.set.length;++r){const l=e.set[r];let u=null,f=null;if(l.forEach(t=>{t.semver===xr&&(t=new Nr(">=0.0.0")),u=u||t,f=f||t,o(t.semver,u.semver,n)?u=t:s(t.semver,f.semver,n)&&(f=t)}),u.operator===a||u.operator===c)return!1;if((!f.operator||f.operator===a)&&i(t,f.semver))return!1;if(f.operator===c&&s(t,f.semver))return!1}return!0};const Fr=Br;var Ur=(t,e,r)=>Fr(t,e,">",r);const Kr=Br;var Gr=(t,e,r)=>Kr(t,e,"<",r);const qr=pr();var Hr=(t,e,r)=>(t=new qr(t,r),e=new qr(e,r),t.intersects(e,r));const Vr=mr,Xr=Ae;const zr=pr(),Wr=hr(),{ANY:Jr}=Wr,Yr=mr,Zr=Ae,Qr=[new Wr(">=0.0.0-0")],tn=[new Wr(">=0.0.0")],en=(t,e,r)=>{if(t===e)return!0;if(1===t.length&&t[0].semver===Jr){if(1===e.length&&e[0].semver===Jr)return!0;t=r.includePrerelease?Qr:tn}if(1===e.length&&e[0].semver===Jr){if(r.includePrerelease)return!0;e=tn}const n=new Set;let o,i,s,a,c,l,u;for(const e of t)">"===e.operator||">="===e.operator?o=rn(o,e,r):"<"===e.operator||"<="===e.operator?i=nn(i,e,r):n.add(e.semver);if(n.size>1)return null;if(o&&i){if(s=Zr(o.semver,i.semver,r),s>0)return null;if(0===s&&(">="!==o.operator||"<="!==i.operator))return null}for(const t of n){if(o&&!Yr(t,String(o),r))return null;if(i&&!Yr(t,String(i),r))return null;for(const n of e)if(!Yr(t,String(n),r))return!1;return!0}let f=!(!i||r.includePrerelease||!i.semver.prerelease.length)&&i.semver,p=!(!o||r.includePrerelease||!o.semver.prerelease.length)&&o.semver;f&&1===f.prerelease.length&&"<"===i.operator&&0===f.prerelease[0]&&(f=!1);for(const t of e){if(u=u||">"===t.operator||">="===t.operator,l=l||"<"===t.operator||"<="===t.operator,o)if(p&&t.semver.prerelease&&t.semver.prerelease.length&&t.semver.major===p.major&&t.semver.minor===p.minor&&t.semver.patch===p.patch&&(p=!1),">"===t.operator||">="===t.operator){if(a=rn(o,t,r),a===t&&a!==o)return!1}else if(">="===o.operator&&!Yr(o.semver,String(t),r))return!1;if(i)if(f&&t.semver.prerelease&&t.semver.prerelease.length&&t.semver.major===f.major&&t.semver.minor===f.minor&&t.semver.patch===f.patch&&(f=!1),"<"===t.operator||"<="===t.operator){if(c=nn(i,t,r),c===t&&c!==i)return!1}else if("<="===i.operator&&!Yr(i.semver,String(t),r))return!1;if(!t.operator&&(i||o)&&0!==s)return!1}return!(o&&l&&!i&&0!==s)&&(!(i&&u&&!o&&0!==s)&&(!p&&!f))},rn=(t,e,r)=>{if(!t)return e;const n=Zr(t.semver,e.semver,r);return n>0?t:n<0||">"===e.operator&&">="===t.operator?e:t},nn=(t,e,r)=>{if(!t)return e;const n=Zr(t.semver,e.semver,r);return n<0?t:n>0||"<"===e.operator&&"<="===t.operator?e:t};var on=(t,e,r={})=>{if(t===e)return!0;t=new zr(t,r),e=new zr(e,r);let n=!1;t:for(const o of t.set){for(const t of e.set){const e=en(o,t,r);if(n=n||null!==e,e)continue t}if(n)return!1}return!0};const sn=Vt,an=qt,cn=se,ln=Zt,un=(t,e,r)=>{const n=[];let o=null,i=null;const s=t.sort((t,e)=>Xr(t,e,r));for(const t of s){Vr(t,e,r)?(i=t,o||(o=t)):(i&&n.push([o,i]),i=null,o=null)}o&&n.push([o,null]);const a=[];for(const[t,e]of n)t===e?a.push(t):e||t!==s[0]?e?t===s[0]?a.push(`<=${e}`):a.push(`${t} - ${e}`):a.push(`>=${t}`):a.push("*");const c=a.join(" || "),l="string"==typeof e.raw?e.raw:String(e);return c.length<l.length?c:e};var fn={parse:ce,valid:ue,clean:pe,inc:de,diff:ge,major:Ee,minor:be,patch:Se,prerelease:Re,compare:Ae,rcompare:ke,compareLoose:Te,compareBuild:xe,sort:je,rsort:Ce,gt:Me,lt:Fe,eq:Ke,neq:qe,gte:Ve,lte:ze,cmp:er,coerce:sr,Comparator:hr(),Range:pr(),satisfies:mr,toComparators:yr,maxSatisfying:br,minSatisfying:$r,minVersion:Or,validRange:Lr,outside:Br,gtr:Ur,ltr:Gr,intersects:Hr,simplifyRange:un,subset:on,SemVer:cn,re:sn.re,src:sn.src,tokens:sn.t,SEMVER_SPEC_VERSION:an.SEMVER_SPEC_VERSION,RELEASE_TYPES:an.RELEASE_TYPES,compareIdentifiers:ln.compareIdentifiers,rcompareIdentifiers:ln.rcompareIdentifiers};var pn=fn.satisfies(process.version,">=15.7.0");var hn=fn.satisfies(process.version,">=16.9.0");const dn=pn,mn=hn,gn={ec:["ES256","ES384","ES512"],rsa:["RS256","PS256","RS384","PS384","RS512","PS512"],"rsa-pss":["PS256","PS384","PS512"]},yn={ES256:"prime256v1",ES384:"secp384r1",ES512:"secp521r1"};var En=function(t,e){if(!t||!e)return;const r=e.asymmetricKeyType;if(!r)return;const n=gn[r];if(!n)throw new Error(`Unknown key type "${r}".`);if(!n.includes(t))throw new Error(`"alg" parameter for "${r}" key type must be one of: ${n.join(", ")}.`);if(dn)switch(r){case"ec":const r=e.asymmetricKeyDetails.namedCurve,n=yn[t];if(r!==n)throw new Error(`"alg" parameter "${t}" requires curve "${n}".`);break;case"rsa-pss":if(mn){const r=parseInt(t.slice(-3),10),{hashAlgorithm:n,mgf1HashAlgorithm:o,saltLength:i}=e.asymmetricKeyDetails;if(n!==`sha${r}`||o!==n)throw new Error(`Invalid key for this operation, its RSA-PSS parameters do not meet the requirements of "alg" ${t}.`);if(void 0!==i&&i>r>>3)throw new Error(`Invalid key for this operation, its RSA-PSS parameter saltLength does not meet the requirements of "alg" ${t}.`)}}},vn=fn.satisfies(process.version,"^6.12.0 || >=8.0.0");const bn=Ot,wn=Tt,Sn=Pt,$n=It,Rn=Kt,In=En,An=vn,On=a,{KeyObject:kn,createSecretKey:Ln,createPublicKey:Tn}=i,Nn=["RS256","RS384","RS512"],xn=["ES256","ES384","ES512"],Pn=["RS256","RS384","RS512"],jn=["HS256","HS384","HS512"];An&&(Nn.splice(Nn.length,0,"PS256","PS384","PS512"),Pn.splice(Pn.length,0,"PS256","PS384","PS512"));var _n=1/0,Cn=9007199254740991,Dn=17976931348623157e292,Mn=NaN,Bn="[object Arguments]",Fn="[object Function]",Un="[object GeneratorFunction]",Kn="[object String]",Gn="[object Symbol]",qn=/^\s+|\s+$/g,Hn=/^[-+]0x[0-9a-f]+$/i,Vn=/^0b[01]+$/i,Xn=/^0o[0-7]+$/i,zn=/^(?:0|[1-9]\d*)$/,Wn=parseInt;function Jn(t){return t!=t}function Yn(t,e){return function(t,e){for(var r=-1,n=t?t.length:0,o=Array(n);++r<n;)o[r]=e(t[r],r,t);return o}(e,function(e){return t[e]})}var Zn,Qn,to=Object.prototype,eo=to.hasOwnProperty,ro=to.toString,no=to.propertyIsEnumerable,oo=(Zn=Object.keys,Qn=Object,function(t){return Zn(Qn(t))}),io=Math.max;function so(t,e){var r=lo(t)||function(t){return function(t){return po(t)&&uo(t)}(t)&&eo.call(t,"callee")&&(!no.call(t,"callee")||ro.call(t)==Bn)}(t)?function(t,e){for(var r=-1,n=Array(t);++r<t;)n[r]=e(r);return n}(t.length,String):[],n=r.length,o=!!n;for(var i in t)!e&&!eo.call(t,i)||o&&("length"==i||co(i,n))||r.push(i);return r}function ao(t){if(r=(e=t)&&e.constructor,n="function"==typeof r&&r.prototype||to,e!==n)return oo(t);var e,r,n,o=[];for(var i in Object(t))eo.call(t,i)&&"constructor"!=i&&o.push(i);return o}function co(t,e){return!!(e=null==e?Cn:e)&&("number"==typeof t||zn.test(t))&&t>-1&&t%1==0&&t<e}var lo=Array.isArray;function uo(t){return null!=t&&function(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=Cn}(t.length)&&!function(t){var e=fo(t)?ro.call(t):"";return e==Fn||e==Un}(t)}function fo(t){var e=typeof t;return!!t&&("object"==e||"function"==e)}function po(t){return!!t&&"object"==typeof t}var ho=function(t,e,r,n){var o;t=uo(t)?t:(o=t)?Yn(o,function(t){return uo(t)?so(t):ao(t)}(o)):[],r=r&&!n?function(t){var e=function(t){if(!t)return 0===t?t:0;if(t=function(t){if("number"==typeof t)return t;if(function(t){return"symbol"==typeof t||po(t)&&ro.call(t)==Gn}(t))return Mn;if(fo(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=fo(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=t.replace(qn,"");var r=Vn.test(t);return r||Xn.test(t)?Wn(t.slice(2),r?2:8):Hn.test(t)?Mn:+t}(t),t===_n||t===-1/0){return(t<0?-1:1)*Dn}return t==t?t:0}(t),r=e%1;return e==e?r?e-r:e:0}(r):0;var i=t.length;return r<0&&(r=io(i+r,0)),function(t){return"string"==typeof t||!lo(t)&&po(t)&&ro.call(t)==Kn}(t)?r<=i&&t.indexOf(e,r)>-1:!!i&&function(t,e,r){if(e!=e)return function(t,e,r,n){for(var o=t.length,i=r+(n?1:-1);n?i--:++i<o;)if(e(t[i],i,t))return i;return-1}(t,Jn,r);for(var n=r-1,o=t.length;++n<o;)if(t[n]===e)return n;return-1}(t,e,r)>-1},mo=Object.prototype.toString;var go=function(t){return!0===t||!1===t||function(t){return!!t&&"object"==typeof t}(t)&&"[object Boolean]"==mo.call(t)},yo=1/0,Eo=17976931348623157e292,vo=NaN,bo="[object Symbol]",wo=/^\s+|\s+$/g,So=/^[-+]0x[0-9a-f]+$/i,$o=/^0b[01]+$/i,Ro=/^0o[0-7]+$/i,Io=parseInt,Ao=Object.prototype.toString;function Oo(t){var e=typeof t;return!!t&&("object"==e||"function"==e)}var ko=function(t){return"number"==typeof t&&t==function(t){var e=function(t){if(!t)return 0===t?t:0;if(t=function(t){if("number"==typeof t)return t;if(function(t){return"symbol"==typeof t||function(t){return!!t&&"object"==typeof t}(t)&&Ao.call(t)==bo}(t))return vo;if(Oo(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=Oo(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=t.replace(wo,"");var r=$o.test(t);return r||Ro.test(t)?Io(t.slice(2),r?2:8):So.test(t)?vo:+t}(t),t===yo||t===-1/0){return(t<0?-1:1)*Eo}return t==t?t:0}(t),r=e%1;return e==e?r?e-r:e:0}(t)},Lo=Object.prototype.toString;var To=function(t){return"number"==typeof t||function(t){return!!t&&"object"==typeof t}(t)&&"[object Number]"==Lo.call(t)};var No=Function.prototype,xo=Object.prototype,Po=No.toString,jo=xo.hasOwnProperty,_o=Po.call(Object),Co=xo.toString,Do=function(t,e){return function(r){return t(e(r))}}(Object.getPrototypeOf,Object);var Mo=function(t){if(!function(t){return!!t&&"object"==typeof t}(t)||"[object Object]"!=Co.call(t)||function(t){var e=!1;if(null!=t&&"function"!=typeof t.toString)try{e=!!(t+"")}catch(t){}return e}(t))return!1;var e=Do(t);if(null===e)return!0;var r=jo.call(e,"constructor")&&e.constructor;return"function"==typeof r&&r instanceof r&&Po.call(r)==_o},Bo=Object.prototype.toString,Fo=Array.isArray;var Uo=function(t){return"string"==typeof t||!Fo(t)&&function(t){return!!t&&"object"==typeof t}(t)&&"[object String]"==Bo.call(t)},Ko=1/0,Go=17976931348623157e292,qo=NaN,Ho="[object Symbol]",Vo=/^\s+|\s+$/g,Xo=/^[-+]0x[0-9a-f]+$/i,zo=/^0b[01]+$/i,Wo=/^0o[0-7]+$/i,Jo=parseInt,Yo=Object.prototype.toString;function Zo(t,e){var r;if("function"!=typeof e)throw new TypeError("Expected a function");return t=function(t){var e=function(t){if(!t)return 0===t?t:0;if(t=function(t){if("number"==typeof t)return t;if(function(t){return"symbol"==typeof t||function(t){return!!t&&"object"==typeof t}(t)&&Yo.call(t)==Ho}(t))return qo;if(Qo(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=Qo(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=t.replace(Vo,"");var r=zo.test(t);return r||Wo.test(t)?Jo(t.slice(2),r?2:8):Xo.test(t)?qo:+t}(t),t===Ko||t===-1/0){return(t<0?-1:1)*Go}return t==t?t:0}(t),r=e%1;return e==e?r?e-r:e:0}(t),function(){return--t>0&&(r=e.apply(this,arguments)),t<=1&&(e=void 0),r}}function Qo(t){var e=typeof t;return!!t&&("object"==e||"function"==e)}var ti=function(t){return Zo(2,t)};const ei=Kt,ri=vn,ni=En,oi=a,ii=ho,si=go,ai=ko,ci=To,li=Mo,ui=Uo,fi=ti,{KeyObject:pi,createSecretKey:hi,createPrivateKey:di}=i,mi=["RS256","RS384","RS512","ES256","ES384","ES512","HS256","HS384","HS512","none"];ri&&mi.splice(3,0,"PS256","PS384","PS512");const gi={expiresIn:{isValid:function(t){return ai(t)||ui(t)&&t},message:'"expiresIn" should be a number of seconds or string representing a timespan'},notBefore:{isValid:function(t){return ai(t)||ui(t)&&t},message:'"notBefore" should be a number of seconds or string representing a timespan'},audience:{isValid:function(t){return ui(t)||Array.isArray(t)},message:'"audience" must be a string or array'},algorithm:{isValid:ii.bind(null,mi),message:'"algorithm" must be a valid string enum value'},header:{isValid:li,message:'"header" must be an object'},encoding:{isValid:ui,message:'"encoding" must be a string'},issuer:{isValid:ui,message:'"issuer" must be a string'},subject:{isValid:ui,message:'"subject" must be a string'},jwtid:{isValid:ui,message:'"jwtid" must be a string'},noTimestamp:{isValid:si,message:'"noTimestamp" must be a boolean'},keyid:{isValid:ui,message:'"keyid" must be a string'},mutatePayload:{isValid:si,message:'"mutatePayload" must be a boolean'},allowInsecureKeySizes:{isValid:si,message:'"allowInsecureKeySizes" must be a boolean'},allowInvalidAsymmetricKeyTypes:{isValid:si,message:'"allowInvalidAsymmetricKeyTypes" must be a boolean'}},yi={iat:{isValid:ci,message:'"iat" should be a number of seconds'},exp:{isValid:ci,message:'"exp" should be a number of seconds'},nbf:{isValid:ci,message:'"nbf" should be a number of seconds'}};function Ei(t,e,r,n){if(!li(r))throw new Error('Expected "'+n+'" to be a plain object.');Object.keys(r).forEach(function(o){const i=t[o];if(i){if(!i.isValid(r[o]))throw new Error(i.message)}else if(!e)throw new Error('"'+o+'" is not allowed in "'+n+'"')})}const vi={audience:"aud",issuer:"iss",subject:"sub",jwtid:"jti"},bi=["expiresIn","notBefore","noTimestamp","audience","issuer","subject","jwtid"];var wi={decode:It,verify:function(t,e,r,n){let o;if("function"!=typeof r||n||(n=r,r={}),r||(r={}),r=Object.assign({},r),o=n||function(t,e){if(t)throw t;return e},r.clockTimestamp&&"number"!=typeof r.clockTimestamp)return o(new bn("clockTimestamp must be a number"));if(void 0!==r.nonce&&("string"!=typeof r.nonce||""===r.nonce.trim()))return o(new bn("nonce must be a non-empty string"));if(void 0!==r.allowInvalidAsymmetricKeyTypes&&"boolean"!=typeof r.allowInvalidAsymmetricKeyTypes)return o(new bn("allowInvalidAsymmetricKeyTypes must be a boolean"));const i=r.clockTimestamp||Math.floor(Date.now()/1e3);if(!t)return o(new bn("jwt must be provided"));if("string"!=typeof t)return o(new bn("jwt must be a string"));const s=t.split(".");if(3!==s.length)return o(new bn("jwt malformed"));let a;try{a=$n(t,{complete:!0})}catch(t){return o(t)}if(!a)return o(new bn("invalid token"));const c=a.header;let l;if("function"==typeof e){if(!n)return o(new bn("verify must be called asynchronous if secret or public key is provided as a callback"));l=e}else l=function(t,r){return r(null,e)};return l(c,function(e,n){if(e)return o(new bn("error in secret or public key callback: "+e.message));const l=""!==s[2].trim();if(!l&&n)return o(new bn("jwt signature is required"));if(l&&!n)return o(new bn("secret or public key must be provided"));if(!l&&!r.algorithms)return o(new bn('please specify "none" in "algorithms" to verify unsigned tokens'));if(null!=n&&!(n instanceof kn))try{n=Tn(n)}catch(t){try{n=Ln("string"==typeof n?Buffer.from(n):n)}catch(t){return o(new bn("secretOrPublicKey is not valid key material"))}}if(r.algorithms||("secret"===n.type?r.algorithms=jn:["rsa","rsa-pss"].includes(n.asymmetricKeyType)?r.algorithms=Pn:"ec"===n.asymmetricKeyType?r.algorithms=xn:r.algorithms=Nn),-1===r.algorithms.indexOf(a.header.alg))return o(new bn("invalid algorithm"));if(c.alg.startsWith("HS")&&"secret"!==n.type)return o(new bn(`secretOrPublicKey must be a symmetric key when using ${c.alg}`));if(/^(?:RS|PS|ES)/.test(c.alg)&&"public"!==n.type)return o(new bn(`secretOrPublicKey must be an asymmetric key when using ${c.alg}`));if(!r.allowInvalidAsymmetricKeyTypes)try{In(c.alg,n)}catch(t){return o(t)}let u;try{u=On.verify(t,a.header.alg,n)}catch(t){return o(t)}if(!u)return o(new bn("invalid signature"));const f=a.payload;if(void 0!==f.nbf&&!r.ignoreNotBefore){if("number"!=typeof f.nbf)return o(new bn("invalid nbf value"));if(f.nbf>i+(r.clockTolerance||0))return o(new wn("jwt not active",new Date(1e3*f.nbf)))}if(void 0!==f.exp&&!r.ignoreExpiration){if("number"!=typeof f.exp)return o(new bn("invalid exp value"));if(i>=f.exp+(r.clockTolerance||0))return o(new Sn("jwt expired",new Date(1e3*f.exp)))}if(r.audience){const t=Array.isArray(r.audience)?r.audience:[r.audience];if(!(Array.isArray(f.aud)?f.aud:[f.aud]).some(function(e){return t.some(function(t){return t instanceof RegExp?t.test(e):t===e})}))return o(new bn("jwt audience invalid. expected: "+t.join(" or ")))}if(r.issuer){if("string"==typeof r.issuer&&f.iss!==r.issuer||Array.isArray(r.issuer)&&-1===r.issuer.indexOf(f.iss))return o(new bn("jwt issuer invalid. expected: "+r.issuer))}if(r.subject&&f.sub!==r.subject)return o(new bn("jwt subject invalid. expected: "+r.subject));if(r.jwtid&&f.jti!==r.jwtid)return o(new bn("jwt jwtid invalid. expected: "+r.jwtid));if(r.nonce&&f.nonce!==r.nonce)return o(new bn("jwt nonce invalid. expected: "+r.nonce));if(r.maxAge){if("number"!=typeof f.iat)return o(new bn("iat required when maxAge is specified"));const t=Rn(r.maxAge,f.iat);if(void 0===t)return o(new bn('"maxAge" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60'));if(i>=t+(r.clockTolerance||0))return o(new Sn("maxAge exceeded",new Date(1e3*t)))}if(!0===r.complete){const t=a.signature;return o(null,{header:c,payload:f,signature:t})}return o(null,f)})},sign:function(t,e,r,n){"function"==typeof r?(n=r,r={}):r=r||{};const o="object"==typeof t&&!Buffer.isBuffer(t),i=Object.assign({alg:r.algorithm||"HS256",typ:o?"JWT":void 0,kid:r.keyid},r.header);function s(t){if(n)return n(t);throw t}if(!e&&"none"!==r.algorithm)return s(new Error("secretOrPrivateKey must have a value"));if(null!=e&&!(e instanceof pi))try{e=di(e)}catch(t){try{e=hi("string"==typeof e?Buffer.from(e):e)}catch(t){return s(new Error("secretOrPrivateKey is not valid key material"))}}if(i.alg.startsWith("HS")&&"secret"!==e.type)return s(new Error(`secretOrPrivateKey must be a symmetric key when using ${i.alg}`));if(/^(?:RS|PS|ES)/.test(i.alg)){if("private"!==e.type)return s(new Error(`secretOrPrivateKey must be an asymmetric key when using ${i.alg}`));if(!r.allowInsecureKeySizes&&!i.alg.startsWith("ES")&&void 0!==e.asymmetricKeyDetails&&e.asymmetricKeyDetails.modulusLength<2048)return s(new Error(`secretOrPrivateKey has a minimum key size of 2048 bits for ${i.alg}`))}if(void 0===t)return s(new Error("payload is required"));if(o){try{!function(t){Ei(yi,!0,t,"payload")}(t)}catch(t){return s(t)}r.mutatePayload||(t=Object.assign({},t))}else{const e=bi.filter(function(t){return void 0!==r[t]});if(e.length>0)return s(new Error("invalid "+e.join(",")+" option for "+typeof t+" payload"))}if(void 0!==t.exp&&void 0!==r.expiresIn)return s(new Error('Bad "options.expiresIn" option the payload already has an "exp" property.'));if(void 0!==t.nbf&&void 0!==r.notBefore)return s(new Error('Bad "options.notBefore" option the payload already has an "nbf" property.'));try{!function(t){Ei(gi,!1,t,"options")}(r)}catch(t){return s(t)}if(!r.allowInvalidAsymmetricKeyTypes)try{ni(i.alg,e)}catch(t){return s(t)}const a=t.iat||Math.floor(Date.now()/1e3);if(r.noTimestamp?delete t.iat:o&&(t.iat=a),void 0!==r.notBefore){try{t.nbf=ei(r.notBefore,a)}catch(t){return s(t)}if(void 0===t.nbf)return s(new Error('"notBefore" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60'))}if(void 0!==r.expiresIn&&"object"==typeof t){try{t.exp=ei(r.expiresIn,a)}catch(t){return s(t)}if(void 0===t.exp)return s(new Error('"expiresIn" should be a number of seconds or string representing a timespan eg: "1d", "20h", 60'))}Object.keys(vi).forEach(function(e){const n=vi[e];if(void 0!==r[e]){if(void 0!==t[n])return s(new Error('Bad "options.'+e+'" option. The payload already has an "'+n+'" property.'));t[n]=r[e]}});const c=r.encoding||"utf8";if("function"!=typeof n){let n=oi.sign({header:i,payload:t,secret:e,encoding:c});if(!r.allowInsecureKeySizes&&/^(?:RS|PS)/.test(i.alg)&&n.length<256)throw new Error(`secretOrPrivateKey has a minimum key size of 2048 bits for ${i.alg}`);return n}n=n&&fi(n),oi.createSign({header:i,privateKey:e,payload:t,encoding:c}).once("error",n).once("done",function(t){if(!r.allowInsecureKeySizes&&/^(?:RS|PS)/.test(i.alg)&&t.length<256)return n(new Error(`secretOrPrivateKey has a minimum key size of 2048 bits for ${i.alg}`));n(null,t)})},JsonWebTokenError:Ot,NotBeforeError:Tt,TokenExpiredError:Pt},Si=s(wi);const $i=t(import.meta.url),{version:Ri}=$i("../package.json");var Ii={id:"sso",handler:(t,r)=>{const{env:n,logger:o,services:i,database:s,getSchema:a}=r,c=n.KEYCLOAK_URL||"http://keycloak:8080",l=n.KEYCLOAK_REALM||"testing",u=n.KEYCLOAK_ADMIN_USER||"admin",f=n.KEYCLOAK_ADMIN_PASSWORD||"admin",p=n.PUBLIC_URL||"http://localhost:8055",h=n.MOBILE_APP_SCHEME||"portalpipq",d=n.MOBILE_APP_CALLBACK_PATH||"/auth/callback",m=n.GOOGLE_CALLBACK_PATH||"/auth/callback/google",g=n.KEYCLOAK_CLIENT_ID||"admin-cli",y=n.COOKIE_DOMAIN||null,E="false"!==n.COOKIE_SECURE,v=n.COOKIE_SAME_SITE||"lax",b=n.SESSION_COOKIE_NAME||"directus_session_token",w=n.REFRESH_TOKEN_COOKIE_NAME||"directus_refresh_token",S="directus_session_token";function $(t){if("browser"===t.query.type)return!0;if("mobile"===t.query.type)return!1;if(t.query.app_scheme||t.query.app_path)return!1;const e=t.headers["user-agent"]||"";return/Mozilla|Chrome|Safari|Firefox|Edge|Opera/i.test(e)&&!/Mobile.*App|ReactNative|Expo/i.test(e)}async function R(t,e){const r=t.headers.cookie;if(!r)return null;const n=r.split(";").map(t=>t.trim()).filter(t=>t.startsWith(`${e}=`)).map(t=>t.substring(e.length+1));if(0===n.length)return null;o.info(`🔍 [${e}] Found ${n.length} possible tokens. Trying them...`);for(let t=0;t<n.length;t++){const r=n[t];try{const n=await fetch(`${p}/users/me`,{headers:{Cookie:`${e}=${r}`}});if(n.ok){const i=await n.json();return o.info(`✅ [${e}] Token #${t+1} succeeded for ${i.data.email}`),{token:r,userData:i.data}}o.info(`❌ [${e}] Token #${t+1} failed (${n.status})`)}catch(r){o.error(`⚠️ [${e}] Error trying token #${t+1}: ${r.message}`)}}return null}async function I(t){const e=t.headers.cookie;if(!e)return null;const r=e.split(";").map(t=>t.trim()).map(t=>{const e=t.split("=");return e.length>1?e[1]:null}).filter(t=>t&&t.startsWith("eyJ")&&t.length>50);if(0===r.length)return null;o.info(`🔍 [MEGA] Found ${r.length} potential JWTs in cookies. Trying them...`);for(let t=0;t<r.length;t++){const e=r[t];try{const r=await fetch(`${p}/users/me`,{headers:{Authorization:`Bearer ${e}`}});if(r.ok){const n=await r.json();return o.info(`✅ [MEGA] Token #${t+1} succeeded for ${n.data.email}`),{token:e,userData:n.data}}}catch(t){}}return null}async function A(t){const e=t.cookies[w];if(!e)return null;o.info(`🔄 [REFRESH] Attempting to use ${w}...`);try{const t=await fetch(`${p}/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refresh_token:e})});if(t.ok){const e=(await t.json()).data.access_token;o.info("✅ [REFRESH] Successfully refreshed session");const r=await fetch(`${p}/users/me`,{headers:{Authorization:`Bearer ${e}`}});if(r.ok){return{token:e,userData:(await r.json()).data}}}}catch(t){o.error("❌ [REFRESH] Failed: "+t.message)}return null}o.info("🚀 Mobile Auth Proxy Extension loaded"),o.info("🔐 Keycloak URL: "+c),o.info("🌐 Keycloak Realm: "+l),o.info("📡 Public URL: "+p),o.info("🍪 Session Cookie Name: "+b),o.info("🍪 Refresh Token Cookie Name: "+w),o.info("📱 Mobile App Scheme: "+h+"://"+d),o.info("🔵 Google OAuth enabled"),t.get("/health",(t,e)=>{e.json({status:"ok",service:"directus-extension-sso",version:Ri})}),t.get("/mobile-callback",async(t,e)=>{const r=$(t);o.info(`${r?"🌐":"📱"} ${r?"Browser":"Mobile"} callback received`),o.info("Host Header: "+t.headers.host),o.info("Cookies Header: "+t.headers.cookie),o.info("Parsed Cookies: "+JSON.stringify(t.cookies)),o.info("Query: "+JSON.stringify(t.query));try{let n=null;if(b!==S&&(n=await R(t,b)),n||(n=await R(t,S)),n||(n=await I(t)),n||(n=await A(t)),!n)return o.error("❌ No valid session or refresh token found in any cookies"),e.send(`\n\t\t\t\t\t\t<html>\n\t\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t\t<h2>Authentication Failed</h2>\n\t\t\t\t\t\t\t\t<p>No valid session found. Please try logging in again.</p>\n\t\t\t\t\t\t\t\t<div style="font-size: 11px; color: #999; margin-top: 20px; text-align: left;">\n\t\t\t\t\t\t\t\t\t<strong>Debug Info (v1.5.4):</strong><br>\n\t\t\t\t\t\t\t\t\tInstance: ${b}<br>\n\t\t\t\t\t\t\t\t\tURL: ${p}<br>\n\t\t\t\t\t\t\t\t\tHost: ${t.headers.host}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<a href="${p}/auth/login/keycloak" style="display: inline-block; margin-top: 20px;">Try Again</a>\n\t\t\t\t\t\t\t</body>\n\t\t\t\t\t\t</html>\n\t\t\t\t\t`);const{token:i,userData:s}=n,a=s.id,c=s.email;o.info("👤 User authenticated: "+a+", "+c);const l=i;if(o.info("🎫 Using session token as access token"),r){o.info("🌐 Browser request detected - maintaining session"),e.cookie(b,i,{httpOnly:!0,secure:E,domain:y,sameSite:v,maxAge:6048e5,path:"/"}),b!==S&&e.cookie(S,"",{maxAge:0,path:"/"});let r=t.query.redirect_uri||t.query.redirect||"/";try{if(r.startsWith("http")){const t=new URL(r);t.searchParams.set("access_token",l),t.searchParams.set("user_id",a),t.searchParams.set("email",c||""),r=t.toString()}}catch(t){o.error("❌ Failed to parse Web redirect URL: "+r)}return o.info("🔄 Redirecting browser to: "+r),e.redirect(r)}const u=t.query.app_scheme||h,f=`${u}://${(t.query.app_path||d).replace(/^\/+/,"")}?access_token=${l}&user_id=${a}&email=${encodeURIComponent(c||"")}`;return o.info("🔄 Attempting AUTO-REDIRECT to app: "+f),e.setHeader("Location",f),e.status(302).send(`\n\t\t\t\t\t<html>\n\t\t\t\t\t\t<head>\n\t\t\t\t\t\t\t<title>Authenticating...</title>\n\t\t\t\t\t\t\t<meta name="viewport" content="width=device-width, initial-scale=1">\n\t\t\t\t\t\t\t<meta http-equiv="refresh" content="0;url=${f}">\n\t\t\t\t\t\t\t<style>\n\t\t\t\t\t\t\t\tbody { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; \n\t\t\t\t\t\t\t\t padding: 40px; text-align: center; background: #fff; }\n\t\t\t\t\t\t\t\t.lds-dual-ring { display: inline-block; width: 40px; height: 40px; margin-bottom: 20px; }\n\t\t\t\t\t\t\t\t.lds-dual-ring:after { content: " "; display: block; width: 32px; height: 32px; margin: 8px; \n\t\t\t\t\t\t\t\t border-radius: 50%; border: 4px solid #4f46e5; \n\t\t\t\t\t\t\t\t\t\t\t\t\t border-color: #4f46e5 transparent #4f46e5 transparent; \n\t\t\t\t\t\t\t\t\t\t\t\t\t animation: lds-dual-ring 1.2s linear infinite; }\n\t\t\t\t\t\t\t\t@keyframes lds-dual-ring { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }\n\t\t\t\t\t\t\t\t.btn { display: inline-block; padding: 12px 24px; background: #4f46e5; color: white; \n\t\t\t\t\t\t\t\t text-decoration: none; border-radius: 6px; font-weight: 500; margin-top: 20px; }\n\t\t\t\t\t\t\t</style>\n\t\t\t\t\t\t</head>\n\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t<div class="lds-dual-ring"></div>\n\t\t\t\t\t\t\t<h2>Finishing Login...</h2>\n\t\t\t\t\t\t\t<p>You are being redirected back to the app.</p>\n\t\t\t\t\t\t\t<p style="font-size: 14px; color: #666; margin-top: 20px;">If the app doesn't open automatically, please click below:</p>\n\t\t\t\t\t\t\t<a id="redirect-btn" href="${f}" class="btn">Return to App</a>\n\t\t\t\t\t\t\t<script>\n\t\t\t\t\t\t\t\t// JavaScript fallback for auto-redirect\n\t\t\t\t\t\t\t\twindow.onload = function() {\n\t\t\t\t\t\t\t\t\twindow.location.href = "${f}";\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t<\/script>\n\t\t\t\t\t\t</body>\n\t\t\t\t\t</html>\n\t\t\t\t`)}catch(t){o.error("❌ Error in callback:",t),e.status(500).send(`\n\t\t<html>\n\t\t\t<body>\n\t\t\t\t<h2>Error</h2>\n\t\t\t\t<p>${t.message}</p>\n\t\t\t\t<a href="${p}/auth/login/keycloak">Try Again</a>\n\t\t\t</body>\n\t\t</html>\n\t`)}}),t.get("/google-callback",async(t,e)=>{const r=$(t);o.info(`${r?"🌐":"📱"} ${r?"Browser":"Mobile"} Google callback received`),o.info("Cookies: "+JSON.stringify(t.cookies)),o.info("Query: "+JSON.stringify(t.query));try{let n=null;if(t.query.access_token&&(o.info("🎟️ Found access_token in URL query string! Bypassing cookie check entirely."),n={access_token:t.query.access_token,refresh_token:t.query.refresh_token||null,expires:t.query.expires||null}),n||b===S||(n=await R(t,b)),n||(n=await R(t,S)),n||(n=await I(t)),n||(n=await A(t)),!n)return o.error("❌ No valid session or refresh token found in any cookies (Google)"),e.send(`\n\t\t\t\t\t\t<html>\n\t\t\t\t\t\t\t<head>\n\t\t\t\t\t\t\t\t<title>Authentication Failed</title>\n\t\t\t\t\t\t\t\t<style>\n\t\t\t\t\t\t\t\t\tbody { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; \n\t\t\t\t\t\t\t\t\t padding: 40px; text-align: center; background: #f5f5f5; }\n\t\t\t\t\t\t\t\t\t.container { max-width: 500px; margin: 0 auto; background: white; \n\t\t\t\t\t\t\t\t\t padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }\n\t\t\t\t\t\t\t\t\th2 { color: #e74c3c; }\n\t\t\t\t\t\t\t\t\t.debug { font-size: 11px; color: #999; margin-top: 20px; text-align: left; }\n\t\t\t\t\t\t\t\t</style>\n\t\t\t\t\t\t\t</head>\n\t\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t\t<div class="container">\n\t\t\t\t\t\t\t\t\t<h2>Authentication Failed</h2>\n\t\t\t\t\t\t\t\t\t<p>No valid session found. Please close this and try logging in again.</p>\n\t\t\t\t\t\t\t\t\t<div class="debug">\n\t\t\t\t\t\t\t\t\t\t<strong>Debug Info (v1.5.4):</strong><br>\n\t\t\t\t\t\t\t\t\t\tInstance: ${b} | Google\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</body>\n\t\t\t\t\t\t</html>\n\t\t\t\t\t`);const{token:i,userData:s}=n,a=s.id,c=s.email,l=s.first_name||s.email;o.info("👤 User authenticated via Google: "+a+", "+c);const u=i;if(o.info("🎫 Using session token as access token"),r){o.info("🌐 Browser request detected - maintaining session"),e.cookie(b,i,{httpOnly:!0,secure:E,domain:y,sameSite:v,maxAge:6048e5,path:"/"}),b!==S&&e.cookie(S,"",{maxAge:0,path:"/"});let r=t.query.redirect_uri||t.query.redirect||"/";try{if(r.startsWith("http")){const t=new URL(r);t.searchParams.set("access_token",u),t.searchParams.set("user_id",a),t.searchParams.set("email",c||""),t.searchParams.set("provider","google"),r=t.toString()}}catch(t){o.error("❌ Failed to parse Web redirect URL: "+r)}return o.info("🔄 Redirecting browser to: "+r),e.send(`\n\t\t\t\t\t\t<html>\n\t\t\t\t\t\t\t<head>\n\t\t\t\t\t\t\t\t<title>Login Successful</title>\n\t\t\t\t\t\t\t\t<meta http-equiv="refresh" content="2;url=${r}">\n\t\t\t\t\t\t\t\t<style>\n\t\t\t\t\t\t\t\t\tbody { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; \n\t\t\t\t\t\t\t\t\t padding: 40px; text-align: center; background: #f5f5f5; }\n\t\t\t\t\t\t\t\t\t.container { max-width: 500px; margin: 0 auto; background: white; \n\t\t\t\t\t\t\t\t\t padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }\n\t\t\t\t\t\t\t\t\th2 { color: #27ae60; }\n\t\t\t\t\t\t\t\t\t.checkmark { font-size: 48px; color: #27ae60; margin-bottom: 20px; }\n\t\t\t\t\t\t\t\t\tp { color: #666; margin: 10px 0; }\n\t\t\t\t\t\t\t\t\t.spinner { border: 3px solid #f3f3f3; border-top: 3px solid #4285f4; \n\t\t\t\t\t\t\t\t\t border-radius: 50%; width: 40px; height: 40px; \n\t\t\t\t\t\t\t\t\t animation: spin 1s linear infinite; margin: 20px auto; }\n\t\t\t\t\t\t\t\t\t@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }\n\t\t\t\t\t\t\t\t\ta { color: #4285f4; text-decoration: none; }\n\t\t\t\t\t\t\t\t\ta:hover { text-decoration: underline; }\n\t\t\t\t\t\t\t\t\t.google-icon { color: #4285f4; margin-right: 5px; }\n\t\t\t\t\t\t\t\t</style>\n\t\t\t\t\t\t\t</head>\n\t\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t\t<div class="container">\n\t\t\t\t\t\t\t\t\t<div class="checkmark">✓</div>\n\t\t\t\t\t\t\t\t\t<h2><span class="google-icon">🔵</span>Google Login Successful!</h2>\n\t\t\t\t\t\t\t\t\t<p>Welcome, ${l}!</p>\n\t\t\t\t\t\t\t\t\t<p>Your session has been saved. You can now access other services using the same login.</p>\n\t\t\t\t\t\t\t\t\t<div class="spinner"></div>\n\t\t\t\t\t\t\t\t\t<p style="margin-top: 20px;">Redirecting you automatically...</p>\n\t\t\t\t\t\t\t\t\t<p style="font-size: 14px; margin-top: 20px;">\n\t\t\t\t\t\t\t\t\t\t<a href="${r}">Click here if not redirected automatically</a>\n\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</body>\n\t\t\t\t\t\t</html>\n\t\t\t\t\t`)}o.info("📱 Mobile app request - redirecting with token");const f=t.query.app_scheme||h,p=t.query.app_path||m,d=new URL(`${f}://${p.replace(/^\/+/,"")}`);return d.searchParams.set("access_token",u),d.searchParams.set("user_id",a),d.searchParams.set("email",c||""),d.searchParams.set("provider","google"),o.info("🔄 Redirecting to app (Google): "+d.toString()),o.info("🚀 Performing direct 302 redirect to app: "+d.toString()),e.redirect(302,d.toString())}catch(t){o.error("❌ Error in Google callback:",t),e.status(500).send(`\n\t\t\t\t\t<html>\n\t\t\t\t\t\t<head>\n\t\t\t\t\t\t\t<title>Error</title>\n\t\t\t\t\t\t\t<style>\n\t\t\t\t\t\t\t\tbody { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; \n\t\t\t\t\t\t\t\t padding: 40px; text-align: center; background: #f5f5f5; }\n\t\t\t\t\t\t\t\t.container { max-width: 500px; margin: 0 auto; background: white; \n\t\t\t\t\t\t\t\t padding: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }\n\t\t\t\t\t\t\t\th2 { color: #e74c3c; }\n\t\t\t\t\t\t\t\t.error-icon { font-size: 48px; color: #e74c3c; margin-bottom: 20px; }\n\t\t\t\t\t\t\t\tpre { background: #f8f8f8; padding: 15px; border-radius: 4px; \n\t\t\t\t\t\t\t\t text-align: left; overflow-x: auto; font-size: 12px; }\n\t\t\t\t\t\t\t\ta { display: inline-block; margin-top: 20px; padding: 10px 20px; \n\t\t\t\t\t\t\t\t background: #4285f4; color: white; text-decoration: none; border-radius: 4px; }\n\t\t\t\t\t\t\t\ta:hover { background: #357ae8; }\n\t\t\t\t\t\t\t</style>\n\t\t\t\t\t\t</head>\n\t\t\t\t\t\t<body>\n\t\t\t\t\t\t\t<div class="container">\n\t\t\t\t\t\t\t\t<div class="error-icon">⚠️</div>\n\t\t\t\t\t\t\t\t<h2>Error</h2>\n\t\t\t\t\t\t\t\t<p>An error occurred during Google authentication:</p>\n\t\t\t\t\t\t\t\t<pre>${t.message}</pre>\n\t\t\t\t\t\t\t\t<a href="${p}/auth/login/google">Try Again</a>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</body>\n\t\t\t\t\t</html>\n\t\t\t\t`)}}),t.post("/mobile-logout",async(t,e)=>{o.info("🚪 Logout request received");try{const r=t.headers.authorization,n=r?.replace("Bearer ","");if(!n)return e.status(400).json({error:"No token provided",message:"Authorization header with Bearer token is required"});o.info("🎫 Token received: "+n.substring(0,20)+"...");let i=null;try{const t=await fetch(`${p}/users/me`,{headers:{Authorization:`Bearer ${n}`}});if(t.ok){i=(await t.json()).data.email,o.info("👤 User email: "+i)}}catch(t){o.error("⚠️ Error getting user info: "+t.message)}try{const t=await fetch(`${p}/auth/logout`,{method:"POST",headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json"},body:JSON.stringify({refresh_token:n})});t.ok?o.info("✅ Directus session invalidated"):o.info("⚠️ Directus logout response: "+t.status)}catch(t){o.error("⚠️ Error logging out from Directus: "+t.message)}if(i)try{o.info("🔐 Getting Keycloak admin token...");const t=await async function(){try{const t=await fetch(`${c}/realms/master/protocol/openid-connect/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"password",client_id:g,username:u,password:f}).toString()});if(!t.ok)throw new Error("Failed to get admin token");return(await t.json()).access_token}catch(t){return o.error("Error getting admin token:",t),null}}();if(t){o.info("🔍 Looking up Keycloak user...");const e=await async function(t,e){try{const r=await fetch(`${c}/admin/realms/${l}/users?email=${encodeURIComponent(e)}`,{headers:{Authorization:`Bearer ${t}`}});if(!r.ok)throw new Error("Failed to get user");const n=await r.json();return n.length>0?n[0].id:null}catch(t){return o.error("Error getting user ID:",t),null}}(t,i);if(e){o.info("🚪 Logging out from Keycloak...");const r=await async function(t,e){try{const r=await fetch(`${c}/admin/realms/${l}/users/${e}/logout`,{method:"POST",headers:{Authorization:`Bearer ${t}`}});return r.ok||204===r.status}catch(t){return o.error("Error logging out user from Keycloak:",t),!1}}(t,e);r?o.info("✅ Keycloak sessions terminated"):o.info("⚠️ Failed to logout from Keycloak")}else o.info("⚠️ User not found in Keycloak")}else o.info("⚠️ Failed to get Keycloak admin token")}catch(t){o.error("⚠️ Error logging out from Keycloak: "+t.message)}o.info("🎉 Logout completed"),e.json({success:!0,message:"Logged out successfully from Directus and Keycloak"})}catch(t){o.error("❌ Error in logout:",t),e.status(500).json({error:t.message,message:"Failed to logout"})}}),t.post("/apple-token",async(t,r)=>{const{identityToken:c,firstName:l,lastName:u}=t.body;if(o.info("🍎 Apple token exchange request received"),!c)return r.status(400).json({error:"identityToken is required",message:"Apple identityToken must be provided in the request body"});try{const t="com.forumbandung.app",f=async r=>{const[n,i,s]=r.split("."),a=JSON.parse(Buffer.from(n,"base64").toString()),c=JSON.parse(Buffer.from(i,"base64").toString());if(o.info("🍎 Apple Token Payload: "+JSON.stringify(c)),"https://appleid.apple.com"!==c.iss)throw new Error("Invalid issuer");const l=[t.toLowerCase(),"host.exp.exponent"],u=c.aud.toLowerCase();if(!l.includes(u))throw o.error(`❌ Invalid audience: ${c.aud}. Expected one of: ${l.join(", ")}`),new Error("Invalid audience");if(c.exp<Math.floor(Date.now()/1e3))throw new Error("Token expired");const f=await fetch("https://appleid.apple.com/auth/keys"),{keys:p}=await f.json(),h=p.find(t=>t.kid===a.kid);if(!h)throw new Error("Apple public key not found");const d=e.createPublicKey({key:h,format:"jwk"}),m=e.createVerify("RSA-SHA256");m.update(`${n}.${i}`);if(!m.verify(d,s,"base64url"))throw new Error("Invalid signature");return c},p=await f(c),{email:h,sub:d}=p;if(!h)throw new Error("Apple token did not contain an email");o.info(`✅ Apple token verified for: ${h} (${d})`);const{UsersService:m,AuthenticationService:g}=i,y=new m({schema:await a(),knex:s}),E=await y.readByQuery({filter:{email:{_eq:h}}});let v,b;E.length>0?(b=E[0],v=b.id,o.info(`👤 Found existing user: ${v}`),b.external_identifier||await y.updateOne(v,{external_identifier:d,provider:"apple"})):(o.info(`📝 Creating new user for: ${h}`),v=await y.createOne({email:h,first_name:l||"Apple User",last_name:u||"",role:n.DEFAULT_ROLE_ID||"36010211-604f-4ce3-84d9-4e69d16781a1",status:"active",provider:"apple",external_identifier:d}),b=await y.readOne(v));try{const t={id:v,role:b.role||n.DEFAULT_ROLE_ID||"36010211-604f-4ce3-84d9-4e69d16781a1",app_access:!0,admin_access:!1},e=Si.sign(t,n.SECRET,{expiresIn:"7d",issuer:"directus"}),o={id:v,type:"refresh"},i=Si.sign(o,n.SECRET,{expiresIn:"30d",issuer:"directus"});r.json({success:!0,data:{access_token:e,refresh_token:i,expires:604800,user:b},user_id:v,email:h,provider:"apple"})}catch(t){o.error("⚠️ Could not generate JWT session token: "+t.message),r.status(500).json({error:"Session error",message:"Apple authentication verified but session generation failed."})}}catch(t){o.error("❌ Error in Apple token exchange:",t),r.status(500).json({error:t.message,message:"Failed to verify Apple token"})}}),t.get("/bridge",async(t,e)=>{const{token:r,redirect_uri:n,redirect:i}=t.query,s=r,a=n||i||"/";if(o.info("🌉 WebView Bridge request received"),!s)return e.status(400).json({error:"Token required",message:"No access token provided"});try{const t=await fetch(`${p}/users/me`,{headers:{Authorization:`Bearer ${s}`}});if(!t.ok)return o.error("❌ Bridge: Invalid token provided"),e.status(401).json({error:"Invalid token",message:"The provided token is invalid or expired"});const r=await t.json();return o.info(`✅ Bridge: Session established for ${r.data.email}`),e.cookie(b,s,{httpOnly:!0,secure:E,domain:y,sameSite:v,maxAge:6048e5,path:"/"}),b!==S&&e.cookie(S,s,{httpOnly:!0,secure:E,domain:y,sameSite:v,maxAge:6048e5,path:"/"}),o.info("🔄 Bridge: Redirecting to "+a),e.redirect(a)}catch(t){o.error("❌ Bridge error: "+t.message),e.status(500).json({error:"Bridge failure",message:t.message})}})}};export{Ii as default};
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@ymys/directus-extension-sso",
|
|
3
3
|
"description": "Mobile OAuth proxy endpoints for Directus + Keycloak + Google",
|
|
4
4
|
"icon": "smartphone",
|
|
5
|
-
"version": "2.0.
|
|
5
|
+
"version": "2.0.6",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"directus",
|
|
8
8
|
"directus-extension",
|
|
@@ -47,7 +47,9 @@
|
|
|
47
47
|
"type": "git",
|
|
48
48
|
"url": "git+https://github.com/ymys/directus-sso.git"
|
|
49
49
|
},
|
|
50
|
-
"dependencies": {
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"jsonwebtoken": "^9.0.3"
|
|
52
|
+
},
|
|
51
53
|
"devDependencies": {
|
|
52
54
|
"@directus/extensions-sdk": "^12.0.2"
|
|
53
55
|
}
|