Skip to content

Commit

Permalink
fix/app dir (#19)
Browse files Browse the repository at this point in the history
* fix: change argon2 to rust implementation

* feat: example with app dir and new docs
  • Loading branch information
fedeya authored Mar 4, 2023
1 parent ab209dc commit 46b9974
Show file tree
Hide file tree
Showing 22 changed files with 731 additions and 1,984 deletions.
87 changes: 9 additions & 78 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,9 +250,9 @@ SanityCredentials(client, 'profile');
signUpHandler(client, 'profile');
```

## Workaround for Module parse failed: Unexpected token
## App Directory

With next@canary and appdir, you may experience the following error;
With next@canary and appDir, you may experience the following error;

```js
./node_modules/@mapbox/node-pre-gyp/lib/util/nw-pre-gyp/index.html
Expand All @@ -264,87 +264,18 @@ You may need an appropriate loader to handle this file type, currently no loader

```

This issue is caused by using argon2 which depends on node. To workaround this for the time being, split your options definitions out into 2 separate files.

`baseOptions.ts`

```ts
import { NextAuthOptions } from 'next-auth';

export const baseOptions: NextAuthOptions = {
providers: [],
session: {
strategy: 'jwt',
},
theme: {
colorScheme: 'light',
brandColor: '#0376bd',
...
},
callbacks: {
jwt({ token, user }) {
if (!user) {
return token;
}
token.role = user.role ?? undefined;
return token;
},
session({ session, user, token }) {
session.user.role = user?.role ?? token?.role ?? undefined;
return session;
},
},
};
```

`authOptions`

```ts
// auth/authOptions.ts

import { NextAuthOptions } from 'next-auth';
import { SanityAdapter, SanityCredentials } from 'next-auth-sanity';
import { baseOptions } from './baseOptions';

export const authOptions: NextAuthOptions = {
...baseOptions,
providers: [
SanityCredentials(client as any),
],
adapter: SanityAdapter(client as any),
};
```

And then use `authOptions` ONLY in your next-auth setup;

`[...nextauth].ts`
This issue is caused by using argon2 which depends on node. To workaround this for the time being, add the next line to your `next.config.js`.

```ts
import NextAuth from 'next-auth';
import { authOptions } from '../../authOptions';

export default NextAuth(authOptions);
```

and then the `baseOptions` everywhere else.

`page.tsx`

```ts
import Manage from './manage';
import { redirect } from 'next/navigation';
import { getServerSession } from 'next-auth/next';
import { authOptions } from '@lib/auth/authOptions';
import { baseOptions } from '@lib/auth/baseOptions';

export default async function Page() {
const session = await getServerSession<typeof authOptions>(baseOptions);
...
// next.config.js
module.exports = {
experimental: {
appDir: true,
serverComponentsExternalPackages: ['argon2'],
}
}
```

`typeof authOptions` is required if you need custom types for our session or user.

## Author

👤 **Fedeya <[email protected]>**
Expand Down
4 changes: 4 additions & 0 deletions examples/full-example/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
}
6 changes: 5 additions & 1 deletion examples/full-example/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
/// <reference types="next" />
/// <reference types="next/types/global" />
/// <reference types="next/image-types/global" />
/// <reference types="next/navigation-types/compat/navigation" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
7 changes: 7 additions & 0 deletions examples/full-example/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/** @type {import('next').NextConfig} */
module.exports = {
experimental: {
appDir: true,
serverComponentsExternalPackages: ['argon2']
}
};
17 changes: 9 additions & 8 deletions examples/full-example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@
"start": "next start"
},
"dependencies": {
"@sanity/client": "^2.8.0",
"next": "10.1.3",
"next-auth": "^4.3.2",
"react": "17.0.2",
"react-dom": "17.0.2"
"@sanity/client": "^5.2.2",
"native-ext-loader": "^2.3.0",
"next": "^13.2.4-canary.2",
"next-auth": "^4.20.1",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/node": "^14.14.41",
"@types/react": "^17.0.3",
"@types/node": "^18.14.6",
"@types/react": "^18.0.28",
"lerna": "^3.22.1",
"typescript": "^4.2.4"
"typescript": "^4.9.5"
}
}
22 changes: 22 additions & 0 deletions examples/full-example/src/app/app/credentials/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { getServerSession } from 'next-auth/next';
import SignUpForm from '@/components/SignUpForm';
import { SignOutButton } from '@/components/Buttons';
import { authOptions } from '@/pages/api/auth/[...nextauth]';

export default async function Credentials() {
const session = await getServerSession(authOptions);

return (
<div>
{session && (
<div>
<p>User: {session.user?.name}</p>
<SignOutButton />
</div>
)}
<h1>Sign Up</h1>

<SignUpForm />
</div>
);
}
22 changes: 22 additions & 0 deletions examples/full-example/src/app/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { getServerSession } from 'next-auth/next';
import { authOptions } from '@/pages/api/auth/[...nextauth]';
import { SignInButton, SignOutButton } from '@/components/Buttons';

export default async function Home() {
const session = await getServerSession(authOptions);

if (session) {
return (
<div>
<p>User: {session?.user?.name}</p>
<SignOutButton />
</div>
);
}

return (
<div>
<SignInButton />
</div>
);
}
9 changes: 9 additions & 0 deletions examples/full-example/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default function RootLayout({ children }) {
return (
<html lang="en">
<head />

<body>{children}</body>
</html>
);
}
10 changes: 10 additions & 0 deletions examples/full-example/src/components/Buttons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use client';
import { signIn, signOut } from 'next-auth/react';

export const SignInButton = () => {
return <button onClick={() => signIn('github')}>Sign In</button>;
};

export const SignOutButton = () => {
return <button onClick={() => signOut({ redirect: false })}>Sign Out</button>;
};
85 changes: 85 additions & 0 deletions examples/full-example/src/components/SignUpForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
'use client';
import { useState } from 'react';
import { signIn } from 'next-auth/react';
import { signUp } from 'next-auth-sanity/client';
import { useRouter } from 'next/navigation';

export default function SignUpForm() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [name, setName] = useState('');
const router = useRouter();

const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();

await signUp({
email,
password,
name
});

await signIn('sanity-login', {
redirect: false,
email,
password
});

router.refresh();
};

const handleSubmitSignIn = async (e: React.FormEvent) => {
e.preventDefault();

await signIn('sanity-login', {
redirect: false,
email,
password
});

router.refresh();
};

return (
<div>
<form onSubmit={handleSubmit}>
<input
type="email"
placeholder="Email"
value={email}
onChange={e => setEmail(e.target.value)}
/>
<input
type="password"
placeholder="Password"
value={password}
onChange={e => setPassword(e.target.value)}
/>
<input
type="name"
placeholder="Name"
value={name}
onChange={e => setName(e.target.value)}
/>
<button type="submit">Create Account</button>
</form>

<h1>Sign In</h1>
<form onSubmit={handleSubmitSignIn}>
<input
type="email"
value={email}
placeholder="Email"
onChange={e => setEmail(e.target.value)}
/>
<input
type="password"
placeholder="Password"
value={password}
onChange={e => setPassword(e.target.value)}
/>
<button type="submit">Sign In</button>
</form>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import createClient from '@sanity/client';
import { createClient } from '@sanity/client';

export const client = createClient({
projectId: process.env.SANITY_PROJECT_ID,
dataset: process.env.SANITY_DATASET,
apiVersion: '2023-01-01',
token: process.env.SANITY_API_TOKEN,
useCdn: process.env.NODE_ENV === 'production'
});
4 changes: 2 additions & 2 deletions examples/full-example/src/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FC } from 'react';
import { AppProps } from 'next/app';
import type { FC } from 'react';
import type { AppProps } from 'next/app';
import { SessionProvider } from 'next-auth/react';

const MyApp: FC<AppProps> = ({ Component, pageProps }) => (
Expand Down
10 changes: 5 additions & 5 deletions examples/full-example/src/pages/api/auth/[...nextauth].ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import NextAuth, { NextAuthOptions } from 'next-auth';
import GitHub from 'next-auth/providers/github';
import { SanityAdapter, SanityCredentials } from 'next-auth-sanity';
import { client } from '../../../libs/sanity';
import { client } from '@/lib/sanity';

const options: NextAuthOptions = {
export const authOptions: NextAuthOptions = {
providers: [
GitHub({
clientId: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET
clientId: process.env.GITHUB_CLIENT_ID!,
clientSecret: process.env.GITHUB_CLIENT_SECRET!
}),
SanityCredentials(client)
],
Expand All @@ -18,4 +18,4 @@ const options: NextAuthOptions = {
adapter: SanityAdapter(client)
};

export default NextAuth(options);
export default NextAuth(authOptions);
2 changes: 1 addition & 1 deletion examples/full-example/src/pages/api/sanity/signUp.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { signUpHandler } from 'next-auth-sanity';
import { client } from '../../../libs/sanity';
import { client } from '@/lib/sanity';

export default signUpHandler(client);
Loading

0 comments on commit 46b9974

Please sign in to comment.