fix onboarding login glitch (#1118)

This commit is contained in:
Alex Johansson 2021-11-08 15:10:02 +01:00 committed by GitHub
parent 9befd4abb9
commit df687009bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 59 additions and 20 deletions

View file

@ -9,6 +9,7 @@ jobs:
DATABASE_URL: postgresql://postgres:@localhost:5432/calendso DATABASE_URL: postgresql://postgres:@localhost:5432/calendso
BASE_URL: http://localhost:3000 BASE_URL: http://localhost:3000
JWT_SECRET: secret JWT_SECRET: secret
GOOGLE_API_CREDENTIALS: "{}"
# GOOGLE_API_CREDENTIALS: ${{ secrets.CI_GOOGLE_API_CREDENTIALS }} # GOOGLE_API_CREDENTIALS: ${{ secrets.CI_GOOGLE_API_CREDENTIALS }}
# CRON_API_KEY: xxx # CRON_API_KEY: xxx
# CALENDSO_ENCRYPTION_KEY: xxx # CALENDSO_ENCRYPTION_KEY: xxx

View file

@ -11,7 +11,7 @@ import {
import { signOut, useSession } from "next-auth/client"; import { signOut, useSession } from "next-auth/client";
import Link from "next/link"; import Link from "next/link";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import React, { ReactNode, useEffect } from "react"; import React, { ReactNode, useEffect, useState } from "react";
import { Toaster } from "react-hot-toast"; import { Toaster } from "react-hot-toast";
import LicenseBanner from "@ee/components/LicenseBanner"; import LicenseBanner from "@ee/components/LicenseBanner";
@ -37,7 +37,11 @@ import { useViewerI18n } from "./I18nLanguageHandler";
import Logo from "./Logo"; import Logo from "./Logo";
function useMeQuery() { function useMeQuery() {
const meQuery = trpc.useQuery(["viewer.me"]); const meQuery = trpc.useQuery(["viewer.me"], {
retry(failureCount) {
return failureCount > 3;
},
});
return meQuery; return meQuery;
} }
@ -45,7 +49,6 @@ function useMeQuery() {
function useRedirectToLoginIfUnauthenticated() { function useRedirectToLoginIfUnauthenticated() {
const [session, loading] = useSession(); const [session, loading] = useSession();
const router = useRouter(); const router = useRouter();
const query = useMeQuery();
useEffect(() => { useEffect(() => {
if (!loading && !session) { if (!loading && !session) {
@ -56,28 +59,36 @@ function useRedirectToLoginIfUnauthenticated() {
}, },
}); });
} }
}, [loading, session, router]); // eslint-disable-next-line react-hooks/exhaustive-deps
}, [loading, session]);
if (query.status !== "loading" && !query.data) { return {
router.replace("/auth/login"); loading: loading && !session,
} };
} }
function useRedirectToOnboardingIfNeeded() { function useRedirectToOnboardingIfNeeded() {
const [session, loading] = useSession();
const router = useRouter(); const router = useRouter();
const query = useMeQuery(); const query = useMeQuery();
const user = query.data; const user = query.data;
const [isRedirectingToOnboarding, setRedirecting] = useState(false);
useEffect(() => { useEffect(() => {
if (!loading && user) { if (user && shouldShowOnboarding(user)) {
if (shouldShowOnboarding(user)) { setRedirecting(true);
router.replace({
pathname: "/getting-started",
});
}
} }
}, [loading, session, router, user]); }, [router, user]);
useEffect(() => {
if (isRedirectingToOnboarding) {
router.replace({
pathname: "/getting-started",
});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isRedirectingToOnboarding]);
return {
isRedirectingToOnboarding,
};
} }
export function ShellSubHeading(props: { export function ShellSubHeading(props: {
@ -109,8 +120,8 @@ export default function Shell(props: {
}) { }) {
const { t } = useLocale(); const { t } = useLocale();
const router = useRouter(); const router = useRouter();
useRedirectToLoginIfUnauthenticated(); const { loading } = useRedirectToLoginIfUnauthenticated();
useRedirectToOnboardingIfNeeded(); const { isRedirectingToOnboarding } = useRedirectToOnboardingIfNeeded();
const telemetry = useTelemetry(); const telemetry = useTelemetry();
@ -157,7 +168,7 @@ export default function Shell(props: {
const i18n = useViewerI18n(); const i18n = useViewerI18n();
if (i18n.status === "loading") { if (i18n.status === "loading" || isRedirectingToOnboarding || loading) {
// show spinner whilst i18n is loading to avoid language flicker // show spinner whilst i18n is loading to avoid language flicker
return ( return (
<div className="z-50 absolute w-full h-screen bg-gray-50 flex items-center"> <div className="z-50 absolute w-full h-screen bg-gray-50 flex items-center">

View file

@ -45,7 +45,7 @@ export function loginProvider(opts: {
if (cachedCookies) { if (cachedCookies) {
await context.addCookies(cachedCookies); await context.addCookies(cachedCookies);
} else { } else {
await page.goto("http://localhost:3000/event-types"); await page.goto("http://localhost:3000/auth/login");
// Click input[name="email"] // Click input[name="email"]
await page.click('input[name="email"]'); await page.click('input[name="email"]');
// Fill input[name="email"] // Fill input[name="email"]
@ -57,7 +57,12 @@ export function loginProvider(opts: {
// Press Enter // Press Enter
await page.press('input[name="password"]', "Enter"); await page.press('input[name="password"]', "Enter");
await page.waitForSelector("[data-testid=event-types]"); await page.waitForNavigation({
url(url) {
return !url.pathname.startsWith("/auth");
},
});
const cookies = await context.cookies(); const cookies = await context.cookies();
cookieCache.set(opts.user, cookies); cookieCache.set(opts.user, cookies);
} }

View file

@ -0,0 +1,22 @@
import { kont } from "kont";
import { loginProvider } from "./lib/loginProvider";
jest.setTimeout(60e3);
jest.retryTimes(2);
const ctx = kont()
.useBeforeEach(
loginProvider({
user: "onboarding",
})
)
.done();
test("redirects to /getting-started after login", async () => {
await ctx.page.waitForNavigation({
url(url) {
return url.pathname === "/getting-started";
},
});
});