One Calendar is a privacy-first calendar web app built with Next.js. It has modern security features, including e2ee, password-protected sharing, and self-destructing share links ๐Ÿ“… calendar.xyehr.cn
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #189 from EvanTechDev/feature/fix-sign-in-login-issues

fix(auth): restore clerk oauth redirect compatibility and sw cache safety

authored by

Evan Huang and committed by
GitHub
2947ec69 9d47660f

+61 -17
+3 -6
app/(auth)/sign-in/sso-callback/page.tsx
··· 1 1 'use client'; 2 2 3 - import { AuthenticateWithRedirectCallback, useClerk } from '@clerk/nextjs'; 3 + import { AuthenticateWithRedirectCallback } from '@clerk/nextjs'; 4 4 import { useEffect } from 'react'; 5 5 6 6 export default function SSOSignInCallback() { 7 - const { setSession } = useClerk(); 8 - 9 7 useEffect(() => { 10 - fetch("/api/atproto/logout", { method: "POST" }).catch(() => undefined); 11 - setSession?.({ forceRedirectUrl: '/app' }); 12 - }, [setSession]); 8 + fetch('/api/atproto/logout', { method: 'POST' }).catch(() => undefined); 9 + }, []); 13 10 14 11 return <AuthenticateWithRedirectCallback />; 15 12 }
+3 -6
app/(auth)/sign-up/sso-callback/page.tsx
··· 1 1 'use client'; 2 2 3 - import { AuthenticateWithRedirectCallback, useClerk } from '@clerk/nextjs'; 3 + import { AuthenticateWithRedirectCallback } from '@clerk/nextjs'; 4 4 import { useEffect } from 'react'; 5 5 6 6 export default function SSOSignUpCallback() { 7 - const { setSession } = useClerk(); 8 - 9 7 useEffect(() => { 10 - fetch("/api/atproto/logout", { method: "POST" }).catch(() => undefined); 11 - setSession?.({ forceRedirectUrl: '/app' }); 12 - }, [setSession]); 8 + fetch('/api/atproto/logout', { method: 'POST' }).catch(() => undefined); 9 + }, []); 13 10 14 11 return <AuthenticateWithRedirectCallback />; 15 12 }
+23 -2
components/auth/login-form.tsx
··· 14 14 className, 15 15 ...props 16 16 }: React.ComponentPropsWithoutRef<"div">) { 17 - const { signIn, setActive } = useSignIn(); 17 + const { isLoaded, signIn, setActive } = useSignIn(); 18 18 const [email, setEmail] = useState(""); 19 19 const [password, setPassword] = useState(""); 20 20 const [isLoading, setIsLoading] = useState(false); ··· 70 70 setError(""); 71 71 72 72 try { 73 + if (!isLoaded || !signIn) { 74 + setError("Auth service is still loading. Please try again in a moment."); 75 + return; 76 + } 77 + 73 78 const result = await signIn.create({ 74 79 identifier: email, 75 80 password, ··· 102 107 setError("Please complete the CAPTCHA verification."); 103 108 return; 104 109 } 105 - signIn.authenticateWithRedirect({ 110 + 111 + if (!isLoaded || !signIn) { 112 + setError("Auth service is still loading. Please try again in a moment."); 113 + return; 114 + } 115 + 116 + const redirect = 117 + signIn.authenticateWithRedirect ?? 118 + (signIn as unknown as { authWithRedirect?: typeof signIn.authenticateWithRedirect }) 119 + .authWithRedirect; 120 + 121 + if (!redirect) { 122 + setError("OAuth is unavailable right now. Please refresh and try again."); 123 + return; 124 + } 125 + 126 + redirect.call(signIn, { 106 127 strategy, 107 128 redirectUrl: "/sign-in/sso-callback", 108 129 redirectUrlComplete: "/app",
+22 -2
components/auth/sign-up-form.tsx
··· 14 14 className, 15 15 ...props 16 16 }: React.ComponentPropsWithoutRef<"div">) { 17 - const { signUp, setActive } = useSignUp(); 17 + const { isLoaded, signUp, setActive } = useSignUp(); 18 18 const router = useRouter(); 19 19 const [step, setStep] = useState<"initial" | "verification">("initial"); 20 20 const [formData, setFormData] = useState({ ··· 135 135 setError("Please complete the CAPTCHA verification."); 136 136 return; 137 137 } 138 - signUp.authenticateWithRedirect({ 138 + if (!isLoaded || !signUp) { 139 + setError("Auth service is still loading. Please try again in a moment."); 140 + return; 141 + } 142 + 143 + const redirect = 144 + signUp.authenticateWithRedirect ?? 145 + (signUp as unknown as { authWithRedirect?: typeof signUp.authenticateWithRedirect }) 146 + .authWithRedirect; 147 + 148 + if (!redirect) { 149 + setError("OAuth is unavailable right now. Please refresh and try again."); 150 + return; 151 + } 152 + 153 + redirect.call(signUp, { 139 154 strategy, 140 155 redirectUrl: "/sign-up/sso-callback", 141 156 redirectUrlComplete: "/app", ··· 153 168 setError(""); 154 169 155 170 try { 171 + if (!isLoaded || !signUp) { 172 + setError("Auth service is still loading. Please try again in a moment."); 173 + return; 174 + } 175 + 156 176 if (step === "initial") { 157 177 if (!isEmailDomainAllowed(formData.email)) { 158 178 setError(
+10 -1
public/sw.js
··· 27 27 self.addEventListener("fetch", (event) => { 28 28 if (event.request.method !== "GET") return; 29 29 30 + const requestUrl = new URL(event.request.url); 31 + if (requestUrl.protocol !== "http:" && requestUrl.protocol !== "https:") { 32 + return; 33 + } 34 + 30 35 event.respondWith( 31 36 caches.match(event.request).then((cachedResponse) => { 32 37 if (cachedResponse) { ··· 39 44 return networkResponse; 40 45 } 41 46 47 + if (networkResponse.type !== "basic") { 48 + return networkResponse; 49 + } 50 + 42 51 const responseToCache = networkResponse.clone(); 43 52 caches.open(CACHE_NAME).then((cache) => { 44 - cache.put(event.request, responseToCache); 53 + cache.put(event.request, responseToCache).catch(() => undefined); 45 54 }); 46 55 47 56 return networkResponse;