Skip to content

Commit

Permalink
Update dependencies and fix authentication issues
Browse files Browse the repository at this point in the history
  • Loading branch information
coji committed Jan 16, 2024
1 parent e85d3bf commit 5bb0c2d
Show file tree
Hide file tree
Showing 12 changed files with 65 additions and 45 deletions.
2 changes: 1 addition & 1 deletion app/routes/_auth+/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Link, type MetaFunction, Outlet } from '@remix-run/react'
import { type MetaFunction, Outlet } from '@remix-run/react'
import { AppUserMenu } from '~/components/AppUserMenu'

export const meta: MetaFunction = () => {
Expand Down
8 changes: 4 additions & 4 deletions app/routes/_auth+/sign_in.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Form, Link, useNavigation } from '@remix-run/react'
import { Form, Link, redirect, useNavigation } from '@remix-run/react'
import {
Button,
Card,
Expand All @@ -13,12 +13,12 @@ import {
DialogTitle,
DialogTrigger,
} from '~/components/ui'
import { getAccountByUID } from '~/models/account'
import { signIn } from '~/services/auth'
import { authenticate } from '~/services/auth'
import { isAuthenticated } from '~/services/auth'

export const clientLoader = async () => {
const user = await authenticate({
registerRedirect: '/welcome',
await isAuthenticated({
successRedirect: '/admin',
})
return null
Expand Down
4 changes: 2 additions & 2 deletions app/routes/_auth+/sign_out.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import {
} from '@remix-run/react'
import { Button } from '~/components/ui/button'
import { signOut } from '~/services/auth'
import { authenticate } from '~/services/auth'
import { isAuthenticated } from '~/services/auth'

export const clientLoader = async () => {
await authenticate({ failureRedirect: '/' })
await isAuthenticated({ failureRedirect: '/' })
return null
}

Expand Down
21 changes: 13 additions & 8 deletions app/routes/_public+/_index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { MetaFunction } from '@remix-run/react'
import { SignInModal } from '~/routes/_auth+/sign_in'
import { authenticate } from '~/services/auth'
import { isAuthenticated } from '~/services/auth'

export const meta: MetaFunction = () => {
return [
Expand All @@ -14,10 +14,7 @@ export const meta: MetaFunction = () => {
}

export const clientLoader = async () => {
await authenticate({
registerRedirect: '/welcome',
successRedirect: '/admin',
})
await isAuthenticated({ successRedirect: '/admin' })
return null
}

Expand All @@ -35,9 +32,17 @@ export default function IndexPage() {
</div>

<div>
ここではなんら有益な情報はもとめられていません。Remix SPA
モードで作った Web
アプリがどんな感じでうごくのか?そんなかんたんな気持ちで、文章を書くための場所です。
catnose さんが開発・運営されている「
<a
className="underline"
target="_blank"
rel="noreferrer"
href="https://sizu.me"
>
しずかなインターネット
</a>
」リスペクトのもと、UI をかなり参考にさせていただいています。
「しずかなインターネットは」とても素敵なサービスです。まだのかたはぜひご利用ください。
</div>

<div className="text-muted-foreground">coji が運営中</div>
Expand Down
10 changes: 3 additions & 7 deletions app/routes/admin+/_index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
import {
ClientActionFunctionArgs,
Form,
Link,
Outlet,
useActionData,
useLoaderData,
useNavigation,
} from '@remix-run/react'
import { authenticate } from '~/services/auth'
import { isAuthenticated } from '~/services/auth'

export const clientLoader = async () => {
await authenticate({ failureRedirect: '/' })
await isAuthenticated({ failureRedirect: '/' })
return null
}

export const clientAction = async ({ request }: ClientActionFunctionArgs) => {
const user = await authenticate({ failureRedirect: '/' })
await isAuthenticated({ failureRedirect: '/' })
return null
}

Expand Down
4 changes: 2 additions & 2 deletions app/routes/admin+/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Link, type MetaFunction, Outlet } from '@remix-run/react'
import { useState } from 'react'
import { AppNavMenu, AppNavMenuButton } from '~/components/AppNavMenu'
import { AppUserMenu } from '~/components/AppUserMenu'
import { authenticate } from '~/services/auth'
import { isAuthenticated } from '~/services/auth'

export const meta: MetaFunction = () => {
return [
Expand All @@ -12,7 +12,7 @@ export const meta: MetaFunction = () => {
}

export const clientLoader = async () => {
await authenticate({ failureRedirect: '/' })
await isAuthenticated({ failureRedirect: '/' })
return null
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { Link } from '@remix-run/react'
import { Button } from '~/components/ui'
import { useSignOut } from '~/routes/_auth+/sign_out'
import { authenticate } from '~/services/auth'
import { isAuthenticated } from '~/services/auth'

export const clientLoader = async () => {
await authenticate({ failureRedirect: '/' })
await isAuthenticated({ failureRedirect: '/' })
return null
}
export default function RegisterProfilePage() {
export default function WelcomeIndexPage() {
const { signOut } = useSignOut()

return (
Expand All @@ -27,7 +27,7 @@ export default function RegisterProfilePage() {
</div>

<Button variant="outline" size="lg" asChild>
<Link to="/account/create" prefetch="render">
<Link to="/welcome/create_account" prefetch="render">
同意する
</Link>
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { z } from 'zod'
import { Alert, AlertDescription, Button, Input } from '~/components/ui'
import { createAccount, isAccountExistsByUID } from '~/models/account'
import { useSignOut } from '~/routes/_auth+/sign_out'
import { authenticate } from '~/services/auth'
import { isAuthenticated } from '~/services/auth'

const createSchema = (
constraint: {
Expand Down Expand Up @@ -39,12 +39,12 @@ const createSchema = (
}

export const clientLoader = async () => {
await authenticate({ failureRedirect: '/' })
await isAuthenticated({ failureRedirect: '/' })
return null
}

export const clientAction = async ({ request }: ClientActionFunctionArgs) => {
const user = await authenticate({ failureRedirect: '/' })
const user = await isAuthenticated({ failureRedirect: '/' })
if (!user) {
throw new Error('User is not authenticated')
}
Expand All @@ -71,7 +71,7 @@ export const clientAction = async ({ request }: ClientActionFunctionArgs) => {
return redirect('/admin')
}

export default function RegisterProfilePage() {
export default function CreateAccountPage() {
const lastSubmission = useActionData<typeof clientAction>()
const [form, { handle }] = useForm({
lastSubmission,
Expand Down
40 changes: 28 additions & 12 deletions app/services/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const useAuthStateObserve = () => {

useEffect(() => {
const auth = getAuth(app)
const unsubscribe = onAuthStateChanged(auth, (user) => {
const unsubscribe = onAuthStateChanged(auth, async (user) => {
setAuthState(user)
})
return () => unsubscribe()
Expand All @@ -32,7 +32,7 @@ export const useAuthStateObserve = () => {
}

/**
* コンポーネントでの認証利用用
* コンポーネントでのユーザ情報利用
*/
export const useAuthUser = () => {
return useContext(AuthContext)
Expand All @@ -42,29 +42,45 @@ export const useAuthUser = () => {
* clientLoader / clientAction での認証確認
* @returns
*/
interface AuthentiateProps {
successRedirect?: string
registerRedirect?: string
failureRedirect?: string
}
export const authenticate = async (props?: AuthentiateProps) => {
export async function isAuthenticated(): Promise<User | never>
export async function isAuthenticated(opts: {
successRedirect: string
}): Promise<User | never>
export async function isAuthenticated(opts: {
failureRedirect: string
}): Promise<User>
export async function isAuthenticated(opts: {
successRedirect: string
failureRedirect: string
}): Promise<never>
export async function isAuthenticated(
opts?:
| { successRedirect: string }
| { failureRedirect: string }
| {
successRedirect: string
failureRedirect: string
},
) {
// 認証初期化を待つ
const auth = getAuth(app)
await auth.authStateReady()

// ログインしていない場合は失敗時のリダイレクト先にリダイレクト
if (!auth.currentUser) {
if (props?.failureRedirect) throw redirect(props?.failureRedirect)
if (opts && 'failureRedirect' in opts) throw redirect(opts?.failureRedirect)
return null
}

// アカウント未登録の場合は初期設定画面にリダイレクト
// FIXME: ページ遷移ごとに認証チェックでこの処理がうごいちゃうのでなんとかしたいけど、外すと直リンクで想定外遷移がされてしまう。。
const account = await getAccountByUID(auth.currentUser.uid)
if (!account && props?.registerRedirect)
throw redirect(props?.registerRedirect)
if (!account) {
return redirect('/welcome')
}

// 登録済みの場合は成功時のリダイレクト先にリダイレクト
if (props?.successRedirect) throw redirect(props?.successRedirect)
if (opts && 'successRedirect' in opts) throw redirect(opts?.successRedirect)

// リダイレクト設定がない場合はユーザ情報をそのまま返す
return auth.currentUser
Expand Down
1 change: 0 additions & 1 deletion app/services/firebase.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// Import the functions you need from the SDKs you need
import { initializeApp } from 'firebase/app'

const firebaseConfig = {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-toast": "^1.1.5",
"@remix-run/node": "^2.5.0",
"@remix-run/react": "^2.5.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
Expand Down
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 5bb0c2d

Please sign in to comment.