diff --git a/examples/authjs/.gitignore b/examples/authjs/.gitignore new file mode 100644 index 00000000..e87bc735 --- /dev/null +++ b/examples/authjs/.gitignore @@ -0,0 +1,24 @@ +# Nuxt dev/build outputs +.output +.data +.nuxt +.nitro +.cache +dist + +# Node dependencies +node_modules + +# Logs +logs +*.log + +# Misc +.DS_Store +.fleet +.idea + +# Local env files +.env +.env.* +!.env.example \ No newline at end of file diff --git a/examples/authjs/.npmrc b/examples/authjs/.npmrc new file mode 100644 index 00000000..50e522c9 --- /dev/null +++ b/examples/authjs/.npmrc @@ -0,0 +1,3 @@ + +shamefully-hoist=true +strict-peer-dependencies=false diff --git a/examples/authjs/README.md b/examples/authjs/README.md new file mode 100644 index 00000000..79eac311 --- /dev/null +++ b/examples/authjs/README.md @@ -0,0 +1,53 @@ +# Authjs Example App (`@sidebase/nuxt-auth`) + +This is a [sidebase merino](https://sidebase.io/) app created by running `pnpm create sidebase@latest`. This project uses the following technologies for a great developer- and user-experience: +- [TypeScript](https://www.typescriptlang.org/) +- [Nuxt 3](https://nuxt.com) +- Tailwind CSS +- nuxt-auth +- GitHub Actions based CI +- Linting via ESLint and @antfu/eslint-config + +## How to get going? + +This is a straight-forward setup with minimal templating and scaffolding. The options you selected during the sidebase CLI setup are all here though. Good places to continue reading are: +- [the First Steps documentation](https://sidebase.io/sidebase/usage) +- [our discord](https://discord.gg/auc8eCeGzx) + +Some tasks you should probably do in the beginning are: +- [ ] replace this generic README with a more specific one +- [ ] install the Vue Volar extension +- [ ] enable [Volar takeover mode](https://nuxt.com/docs/getting-started/installation#prerequisites) to ensure a smooth editor setup +- [ ] [install Nuxt 3 devtools](https://github.com/nuxt/devtools#installation) if you want to use them +- [ ] Auth: Configure your auth providers to the [NuxtAuthHandler](./server/api/auth/[...].ts) +- [ ] Auth, optional: Enable global protection by setting `enableGlobalAppMiddleware: true` in [your nuxt.config.ts](./nuxt.config.ts). Delete the local middleware in the [protected.vue](./pages/protected.vue) page if you do + +### Setup + +Make sure to install the dependencies: + +```bash +pnpm install +``` + +### Development Server + +Start the development server on http://localhost:3000 + +```bash +pnpm run dev +``` + +### Production + +Build the application for production: + +```bash +pnpm run build +``` + +Locally preview production build: + +```bash +pnpm run preview +``` diff --git a/examples/authjs/app.vue b/examples/authjs/app.vue new file mode 100644 index 00000000..2b1be090 --- /dev/null +++ b/examples/authjs/app.vue @@ -0,0 +1,5 @@ + diff --git a/examples/authjs/components/Welcome/AuthDemo.vue b/examples/authjs/components/Welcome/AuthDemo.vue new file mode 100644 index 00000000..9eaa127b --- /dev/null +++ b/examples/authjs/components/Welcome/AuthDemo.vue @@ -0,0 +1,35 @@ + + + diff --git a/examples/authjs/components/Welcome/ButtonLink.vue b/examples/authjs/components/Welcome/ButtonLink.vue new file mode 100644 index 00000000..d31666c5 --- /dev/null +++ b/examples/authjs/components/Welcome/ButtonLink.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/examples/authjs/components/Welcome/TailwindDemo.vue b/examples/authjs/components/Welcome/TailwindDemo.vue new file mode 100644 index 00000000..20a642e6 --- /dev/null +++ b/examples/authjs/components/Welcome/TailwindDemo.vue @@ -0,0 +1,22 @@ + diff --git a/examples/authjs/eslint.config.js b/examples/authjs/eslint.config.js new file mode 100644 index 00000000..ea396fa1 --- /dev/null +++ b/examples/authjs/eslint.config.js @@ -0,0 +1,41 @@ +import antfu from '@antfu/eslint-config' + +const ignores = [ + '.nuxt', + '**/.nuxt/**', + '.output', + '**/.output/**', + 'node_modules', + '**/node_modules/**', + 'public', + '**/public/**', +] + +export default antfu({ + // .eslintignore is no longer supported in Flat config, use ignores instead + ignores, + + // Stylistic formatting rules + stylistic: { + indent: 2, + quotes: 'single', + }, + + // TypeScript and Vue are auto-detected, you can also explicitly enable them + typescript: true, + vue: true, + + // Disable jsonc and yaml support + jsonc: false, + yaml: false, + + // Overwrite certain rules to your preference + rules: { + 'no-console': ['error', { + allow: ['info', 'warn', 'trace', 'error', 'group', 'groupEnd'], + }], + 'style/comma-dangle': 'off', + 'curly': ['error', 'all'], + 'node/prefer-global/process': ['error', 'always'], + }, +}) diff --git a/examples/authjs/nuxt.config.ts b/examples/authjs/nuxt.config.ts new file mode 100644 index 00000000..bec1fde0 --- /dev/null +++ b/examples/authjs/nuxt.config.ts @@ -0,0 +1,10 @@ +// https://nuxt.com/docs/api/configuration/nuxt-config +export default defineNuxtConfig({ + modules: [ + '@nuxtjs/tailwindcss', + '@sidebase/nuxt-auth' + ], + typescript: { + shim: false + } +}) diff --git a/examples/authjs/package.json b/examples/authjs/package.json new file mode 100644 index 00000000..cfec50af --- /dev/null +++ b/examples/authjs/package.json @@ -0,0 +1,34 @@ +{ + "name": "nuxt-app", + "private": true, + "type": "module", + "scripts": { + "start": "NODE_ENV=production node .output/server/index.mjs", + "typecheck": "nuxt typecheck", + "lint:fix": "eslint . --fix", + "lint": "oxlint --deny-warnings -D correctness -D suspicious -D perf && eslint --max-warnings 0 .", + "build": "nuxt build", + "dev": "nuxt dev", + "generate": "nuxt generate", + "preview": "nuxt preview", + "postinstall": "nuxt prepare" + }, + "dependencies": { + "nuxt": "^3.12.2", + "vue": "^3.4.29", + "vue-router": "^4.3.3" + }, + "devDependencies": { + "@sidebase/nuxt-auth": "^0.7.2", + "@nuxtjs/tailwindcss": "^6.11.4", + "@types/node": "^20.11.30", + "typescript": "^5.4.3", + "vue-tsc": "^2.0.7", + "oxlint": "^0.2.15", + "@antfu/eslint-config": "^2.11.5", + "eslint": "^8.57.0" + }, + "peerDependencies": { + "next-auth": "4.21.1" + } +} diff --git a/examples/authjs/pages/index.vue b/examples/authjs/pages/index.vue new file mode 100644 index 00000000..05357015 --- /dev/null +++ b/examples/authjs/pages/index.vue @@ -0,0 +1,220 @@ + + + diff --git a/examples/authjs/public/favicon.ico b/examples/authjs/public/favicon.ico new file mode 100644 index 00000000..b3d1e39f Binary files /dev/null and b/examples/authjs/public/favicon.ico differ diff --git a/examples/authjs/server/api/auth/[...].ts b/examples/authjs/server/api/auth/[...].ts new file mode 100644 index 00000000..8ea20e8f --- /dev/null +++ b/examples/authjs/server/api/auth/[...].ts @@ -0,0 +1,51 @@ +import CredentialsProvider from 'next-auth/providers/credentials' +import GithubProvider from 'next-auth/providers/github' +import { NuxtAuthHandler } from '#auth' + +export default NuxtAuthHandler({ + // TODO: SET A STRONG SECRET, SEE https://sidebase.io/nuxt-auth/configuration/nuxt-auth-handler#secret + secret: process.env.AUTH_SECRET, + // TODO: ADD YOUR OWN AUTHENTICATION PROVIDER HERE, READ THE DOCS FOR MORE: https://sidebase.io/nuxt-auth + providers: [ + // @ts-expect-error You need to use .default here for it to work during SSR. May be fixed via Vite at some point + GithubProvider.default({ + clientId: process.env.GITHUB_CLIENT_ID || 'enter-your-client-id-here', + clientSecret: process.env.GITHUB_CLIENT_SECRET || 'enter-your-client-secret-here', // TODO: Replace this with an env var like "process.env.GITHUB_CLIENT_SECRET". The secret should never end up in your github repository + }), + // @ts-expect-error You need to use .default here for it to work during SSR. May be fixed via Vite at some point + CredentialsProvider.default({ + // The name to display on the sign in form (e.g. 'Sign in with...') + name: 'Credentials', + // The credentials is used to generate a suitable form on the sign in page. + // You can specify whatever fields you are expecting to be submitted. + // e.g. domain, username, password, 2FA token, etc. + // You can pass any HTML attribute to the tag through the object. + credentials: { + username: { label: 'Username', type: 'text', placeholder: '(hint: jsmith)' }, + password: { label: 'Password', type: 'password', placeholder: '(hint: hunter2)' }, + }, + authorize(credentials: any) { + console.warn('ATTENTION: You should replace this with your real providers or credential provider logic! The current setup is not safe') + // You need to provide your own logic here that takes the credentials + // submitted and returns either a object representing a user or value + // that is false/null if the credentials are invalid. + // NOTE: THE BELOW LOGIC IS NOT SAFE OR PROPER FOR AUTHENTICATION! + + const user = { id: '1', name: 'J Smith', username: 'jsmith', password: 'hunter2' } + + if (credentials?.username === user.username && credentials?.password === user.password) { + // Any object returned will be saved in `user` property of the JWT + return user + } + else { + console.error('Warning: Malicious login attempt registered, bad credentials provided') + + // If you return null then an error will be displayed advising the user to check their details. + return null + + // You can also Reject this callback with an Error thus the user will be sent to the error page with the error message as a query parameter + } + }, + }), + ], +}) diff --git a/examples/authjs/server/tsconfig.json b/examples/authjs/server/tsconfig.json new file mode 100644 index 00000000..b9ed69c1 --- /dev/null +++ b/examples/authjs/server/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../.nuxt/tsconfig.server.json" +} diff --git a/examples/authjs/tsconfig.json b/examples/authjs/tsconfig.json new file mode 100644 index 00000000..a746f2a7 --- /dev/null +++ b/examples/authjs/tsconfig.json @@ -0,0 +1,4 @@ +{ + // https://nuxt.com/docs/guide/concepts/typescript + "extends": "./.nuxt/tsconfig.json" +} diff --git a/examples/local/.gitignore b/examples/local/.gitignore new file mode 100644 index 00000000..e87bc735 --- /dev/null +++ b/examples/local/.gitignore @@ -0,0 +1,24 @@ +# Nuxt dev/build outputs +.output +.data +.nuxt +.nitro +.cache +dist + +# Node dependencies +node_modules + +# Logs +logs +*.log + +# Misc +.DS_Store +.fleet +.idea + +# Local env files +.env +.env.* +!.env.example \ No newline at end of file diff --git a/examples/local/.npmrc b/examples/local/.npmrc new file mode 100644 index 00000000..50e522c9 --- /dev/null +++ b/examples/local/.npmrc @@ -0,0 +1,3 @@ + +shamefully-hoist=true +strict-peer-dependencies=false diff --git a/examples/local/README.md b/examples/local/README.md new file mode 100644 index 00000000..da1a814f --- /dev/null +++ b/examples/local/README.md @@ -0,0 +1,53 @@ +# Local Example App (`@sidebase/nuxt-auth`) + +This is a [sidebase merino](https://sidebase.io/) app created by running `pnpm create sidebase@latest`. This project uses the following technologies for a great developer- and user-experience: +- [TypeScript](https://www.typescriptlang.org/) +- [Nuxt 3](https://nuxt.com) +- Tailwind CSS +- nuxt-auth +- GitHub Actions based CI +- Linting via ESLint and @antfu/eslint-config + +## How to get going? + +This is a straight-forward setup with minimal templating and scaffolding. The options you selected during the sidebase CLI setup are all here though. Good places to continue reading are: +- [the First Steps documentation](https://sidebase.io/sidebase/usage) +- [our discord](https://discord.gg/auc8eCeGzx) + +Some tasks you should probably do in the beginning are: +- [ ] replace this generic README with a more specific one +- [ ] install the Vue Volar extension +- [ ] enable [Volar takeover mode](https://nuxt.com/docs/getting-started/installation#prerequisites) to ensure a smooth editor setup +- [ ] [install Nuxt 3 devtools](https://github.com/nuxt/devtools#installation) if you want to use them +- [ ] Auth: Configure your auth providers to the [NuxtAuthHandler](./server/api/auth/[...].ts) +- [ ] Auth, optional: Enable global protection by setting `enableGlobalAppMiddleware: true` in [your nuxt.config.ts](./nuxt.config.ts). Delete the local middleware in the [protected.vue](./pages/protected.vue) page if you do + +### Setup + +Make sure to install the dependencies: + +```bash +pnpm install +``` + +### Development Server + +Start the development server on http://localhost:3000 + +```bash +pnpm run dev +``` + +### Production + +Build the application for production: + +```bash +pnpm run build +``` + +Locally preview production build: + +```bash +pnpm run preview +``` diff --git a/examples/local/app.vue b/examples/local/app.vue new file mode 100644 index 00000000..2b1be090 --- /dev/null +++ b/examples/local/app.vue @@ -0,0 +1,5 @@ + diff --git a/examples/local/components/Welcome/AuthDemo.vue b/examples/local/components/Welcome/AuthDemo.vue new file mode 100644 index 00000000..9eaa127b --- /dev/null +++ b/examples/local/components/Welcome/AuthDemo.vue @@ -0,0 +1,35 @@ + + + diff --git a/examples/local/components/Welcome/ButtonLink.vue b/examples/local/components/Welcome/ButtonLink.vue new file mode 100644 index 00000000..d31666c5 --- /dev/null +++ b/examples/local/components/Welcome/ButtonLink.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/examples/local/components/Welcome/TailwindDemo.vue b/examples/local/components/Welcome/TailwindDemo.vue new file mode 100644 index 00000000..20a642e6 --- /dev/null +++ b/examples/local/components/Welcome/TailwindDemo.vue @@ -0,0 +1,22 @@ + diff --git a/examples/local/eslint.config.js b/examples/local/eslint.config.js new file mode 100644 index 00000000..ea396fa1 --- /dev/null +++ b/examples/local/eslint.config.js @@ -0,0 +1,41 @@ +import antfu from '@antfu/eslint-config' + +const ignores = [ + '.nuxt', + '**/.nuxt/**', + '.output', + '**/.output/**', + 'node_modules', + '**/node_modules/**', + 'public', + '**/public/**', +] + +export default antfu({ + // .eslintignore is no longer supported in Flat config, use ignores instead + ignores, + + // Stylistic formatting rules + stylistic: { + indent: 2, + quotes: 'single', + }, + + // TypeScript and Vue are auto-detected, you can also explicitly enable them + typescript: true, + vue: true, + + // Disable jsonc and yaml support + jsonc: false, + yaml: false, + + // Overwrite certain rules to your preference + rules: { + 'no-console': ['error', { + allow: ['info', 'warn', 'trace', 'error', 'group', 'groupEnd'], + }], + 'style/comma-dangle': 'off', + 'curly': ['error', 'all'], + 'node/prefer-global/process': ['error', 'always'], + }, +}) diff --git a/examples/local/nuxt.config.ts b/examples/local/nuxt.config.ts new file mode 100644 index 00000000..bec1fde0 --- /dev/null +++ b/examples/local/nuxt.config.ts @@ -0,0 +1,10 @@ +// https://nuxt.com/docs/api/configuration/nuxt-config +export default defineNuxtConfig({ + modules: [ + '@nuxtjs/tailwindcss', + '@sidebase/nuxt-auth' + ], + typescript: { + shim: false + } +}) diff --git a/examples/local/package.json b/examples/local/package.json new file mode 100644 index 00000000..cfec50af --- /dev/null +++ b/examples/local/package.json @@ -0,0 +1,34 @@ +{ + "name": "nuxt-app", + "private": true, + "type": "module", + "scripts": { + "start": "NODE_ENV=production node .output/server/index.mjs", + "typecheck": "nuxt typecheck", + "lint:fix": "eslint . --fix", + "lint": "oxlint --deny-warnings -D correctness -D suspicious -D perf && eslint --max-warnings 0 .", + "build": "nuxt build", + "dev": "nuxt dev", + "generate": "nuxt generate", + "preview": "nuxt preview", + "postinstall": "nuxt prepare" + }, + "dependencies": { + "nuxt": "^3.12.2", + "vue": "^3.4.29", + "vue-router": "^4.3.3" + }, + "devDependencies": { + "@sidebase/nuxt-auth": "^0.7.2", + "@nuxtjs/tailwindcss": "^6.11.4", + "@types/node": "^20.11.30", + "typescript": "^5.4.3", + "vue-tsc": "^2.0.7", + "oxlint": "^0.2.15", + "@antfu/eslint-config": "^2.11.5", + "eslint": "^8.57.0" + }, + "peerDependencies": { + "next-auth": "4.21.1" + } +} diff --git a/examples/local/pages/index.vue b/examples/local/pages/index.vue new file mode 100644 index 00000000..05357015 --- /dev/null +++ b/examples/local/pages/index.vue @@ -0,0 +1,220 @@ + + + diff --git a/examples/local/public/favicon.ico b/examples/local/public/favicon.ico new file mode 100644 index 00000000..b3d1e39f Binary files /dev/null and b/examples/local/public/favicon.ico differ diff --git a/examples/local/server/api/auth/[...].ts b/examples/local/server/api/auth/[...].ts new file mode 100644 index 00000000..8ea20e8f --- /dev/null +++ b/examples/local/server/api/auth/[...].ts @@ -0,0 +1,51 @@ +import CredentialsProvider from 'next-auth/providers/credentials' +import GithubProvider from 'next-auth/providers/github' +import { NuxtAuthHandler } from '#auth' + +export default NuxtAuthHandler({ + // TODO: SET A STRONG SECRET, SEE https://sidebase.io/nuxt-auth/configuration/nuxt-auth-handler#secret + secret: process.env.AUTH_SECRET, + // TODO: ADD YOUR OWN AUTHENTICATION PROVIDER HERE, READ THE DOCS FOR MORE: https://sidebase.io/nuxt-auth + providers: [ + // @ts-expect-error You need to use .default here for it to work during SSR. May be fixed via Vite at some point + GithubProvider.default({ + clientId: process.env.GITHUB_CLIENT_ID || 'enter-your-client-id-here', + clientSecret: process.env.GITHUB_CLIENT_SECRET || 'enter-your-client-secret-here', // TODO: Replace this with an env var like "process.env.GITHUB_CLIENT_SECRET". The secret should never end up in your github repository + }), + // @ts-expect-error You need to use .default here for it to work during SSR. May be fixed via Vite at some point + CredentialsProvider.default({ + // The name to display on the sign in form (e.g. 'Sign in with...') + name: 'Credentials', + // The credentials is used to generate a suitable form on the sign in page. + // You can specify whatever fields you are expecting to be submitted. + // e.g. domain, username, password, 2FA token, etc. + // You can pass any HTML attribute to the tag through the object. + credentials: { + username: { label: 'Username', type: 'text', placeholder: '(hint: jsmith)' }, + password: { label: 'Password', type: 'password', placeholder: '(hint: hunter2)' }, + }, + authorize(credentials: any) { + console.warn('ATTENTION: You should replace this with your real providers or credential provider logic! The current setup is not safe') + // You need to provide your own logic here that takes the credentials + // submitted and returns either a object representing a user or value + // that is false/null if the credentials are invalid. + // NOTE: THE BELOW LOGIC IS NOT SAFE OR PROPER FOR AUTHENTICATION! + + const user = { id: '1', name: 'J Smith', username: 'jsmith', password: 'hunter2' } + + if (credentials?.username === user.username && credentials?.password === user.password) { + // Any object returned will be saved in `user` property of the JWT + return user + } + else { + console.error('Warning: Malicious login attempt registered, bad credentials provided') + + // If you return null then an error will be displayed advising the user to check their details. + return null + + // You can also Reject this callback with an Error thus the user will be sent to the error page with the error message as a query parameter + } + }, + }), + ], +}) diff --git a/examples/local/server/tsconfig.json b/examples/local/server/tsconfig.json new file mode 100644 index 00000000..b9ed69c1 --- /dev/null +++ b/examples/local/server/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../.nuxt/tsconfig.server.json" +} diff --git a/examples/local/tsconfig.json b/examples/local/tsconfig.json new file mode 100644 index 00000000..a746f2a7 --- /dev/null +++ b/examples/local/tsconfig.json @@ -0,0 +1,4 @@ +{ + // https://nuxt.com/docs/guide/concepts/typescript + "extends": "./.nuxt/tsconfig.json" +} diff --git a/examples/refresh/.gitignore b/examples/refresh/.gitignore new file mode 100644 index 00000000..e87bc735 --- /dev/null +++ b/examples/refresh/.gitignore @@ -0,0 +1,24 @@ +# Nuxt dev/build outputs +.output +.data +.nuxt +.nitro +.cache +dist + +# Node dependencies +node_modules + +# Logs +logs +*.log + +# Misc +.DS_Store +.fleet +.idea + +# Local env files +.env +.env.* +!.env.example \ No newline at end of file diff --git a/examples/refresh/.npmrc b/examples/refresh/.npmrc new file mode 100644 index 00000000..50e522c9 --- /dev/null +++ b/examples/refresh/.npmrc @@ -0,0 +1,3 @@ + +shamefully-hoist=true +strict-peer-dependencies=false diff --git a/examples/refresh/README.md b/examples/refresh/README.md new file mode 100644 index 00000000..aafdc295 --- /dev/null +++ b/examples/refresh/README.md @@ -0,0 +1,53 @@ +# Refresh Example App (`@sidebase/nuxt-auth`) + +This is a [sidebase merino](https://sidebase.io/) app created by running `pnpm create sidebase@latest`. This project uses the following technologies for a great developer- and user-experience: +- [TypeScript](https://www.typescriptlang.org/) +- [Nuxt 3](https://nuxt.com) +- Tailwind CSS +- nuxt-auth +- GitHub Actions based CI +- Linting via ESLint and @antfu/eslint-config + +## How to get going? + +This is a straight-forward setup with minimal templating and scaffolding. The options you selected during the sidebase CLI setup are all here though. Good places to continue reading are: +- [the First Steps documentation](https://sidebase.io/sidebase/usage) +- [our discord](https://discord.gg/auc8eCeGzx) + +Some tasks you should probably do in the beginning are: +- [ ] replace this generic README with a more specific one +- [ ] install the Vue Volar extension +- [ ] enable [Volar takeover mode](https://nuxt.com/docs/getting-started/installation#prerequisites) to ensure a smooth editor setup +- [ ] [install Nuxt 3 devtools](https://github.com/nuxt/devtools#installation) if you want to use them +- [ ] Auth: Configure your auth providers to the [NuxtAuthHandler](./server/api/auth/[...].ts) +- [ ] Auth, optional: Enable global protection by setting `enableGlobalAppMiddleware: true` in [your nuxt.config.ts](./nuxt.config.ts). Delete the local middleware in the [protected.vue](./pages/protected.vue) page if you do + +### Setup + +Make sure to install the dependencies: + +```bash +pnpm install +``` + +### Development Server + +Start the development server on http://localhost:3000 + +```bash +pnpm run dev +``` + +### Production + +Build the application for production: + +```bash +pnpm run build +``` + +Locally preview production build: + +```bash +pnpm run preview +``` diff --git a/examples/refresh/app.vue b/examples/refresh/app.vue new file mode 100644 index 00000000..2b1be090 --- /dev/null +++ b/examples/refresh/app.vue @@ -0,0 +1,5 @@ + diff --git a/examples/refresh/components/Welcome/AuthDemo.vue b/examples/refresh/components/Welcome/AuthDemo.vue new file mode 100644 index 00000000..9eaa127b --- /dev/null +++ b/examples/refresh/components/Welcome/AuthDemo.vue @@ -0,0 +1,35 @@ + + + diff --git a/examples/refresh/components/Welcome/ButtonLink.vue b/examples/refresh/components/Welcome/ButtonLink.vue new file mode 100644 index 00000000..d31666c5 --- /dev/null +++ b/examples/refresh/components/Welcome/ButtonLink.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/examples/refresh/components/Welcome/TailwindDemo.vue b/examples/refresh/components/Welcome/TailwindDemo.vue new file mode 100644 index 00000000..20a642e6 --- /dev/null +++ b/examples/refresh/components/Welcome/TailwindDemo.vue @@ -0,0 +1,22 @@ + diff --git a/examples/refresh/eslint.config.js b/examples/refresh/eslint.config.js new file mode 100644 index 00000000..ea396fa1 --- /dev/null +++ b/examples/refresh/eslint.config.js @@ -0,0 +1,41 @@ +import antfu from '@antfu/eslint-config' + +const ignores = [ + '.nuxt', + '**/.nuxt/**', + '.output', + '**/.output/**', + 'node_modules', + '**/node_modules/**', + 'public', + '**/public/**', +] + +export default antfu({ + // .eslintignore is no longer supported in Flat config, use ignores instead + ignores, + + // Stylistic formatting rules + stylistic: { + indent: 2, + quotes: 'single', + }, + + // TypeScript and Vue are auto-detected, you can also explicitly enable them + typescript: true, + vue: true, + + // Disable jsonc and yaml support + jsonc: false, + yaml: false, + + // Overwrite certain rules to your preference + rules: { + 'no-console': ['error', { + allow: ['info', 'warn', 'trace', 'error', 'group', 'groupEnd'], + }], + 'style/comma-dangle': 'off', + 'curly': ['error', 'all'], + 'node/prefer-global/process': ['error', 'always'], + }, +}) diff --git a/examples/refresh/nuxt.config.ts b/examples/refresh/nuxt.config.ts new file mode 100644 index 00000000..bec1fde0 --- /dev/null +++ b/examples/refresh/nuxt.config.ts @@ -0,0 +1,10 @@ +// https://nuxt.com/docs/api/configuration/nuxt-config +export default defineNuxtConfig({ + modules: [ + '@nuxtjs/tailwindcss', + '@sidebase/nuxt-auth' + ], + typescript: { + shim: false + } +}) diff --git a/examples/refresh/package.json b/examples/refresh/package.json new file mode 100644 index 00000000..cfec50af --- /dev/null +++ b/examples/refresh/package.json @@ -0,0 +1,34 @@ +{ + "name": "nuxt-app", + "private": true, + "type": "module", + "scripts": { + "start": "NODE_ENV=production node .output/server/index.mjs", + "typecheck": "nuxt typecheck", + "lint:fix": "eslint . --fix", + "lint": "oxlint --deny-warnings -D correctness -D suspicious -D perf && eslint --max-warnings 0 .", + "build": "nuxt build", + "dev": "nuxt dev", + "generate": "nuxt generate", + "preview": "nuxt preview", + "postinstall": "nuxt prepare" + }, + "dependencies": { + "nuxt": "^3.12.2", + "vue": "^3.4.29", + "vue-router": "^4.3.3" + }, + "devDependencies": { + "@sidebase/nuxt-auth": "^0.7.2", + "@nuxtjs/tailwindcss": "^6.11.4", + "@types/node": "^20.11.30", + "typescript": "^5.4.3", + "vue-tsc": "^2.0.7", + "oxlint": "^0.2.15", + "@antfu/eslint-config": "^2.11.5", + "eslint": "^8.57.0" + }, + "peerDependencies": { + "next-auth": "4.21.1" + } +} diff --git a/examples/refresh/pages/index.vue b/examples/refresh/pages/index.vue new file mode 100644 index 00000000..05357015 --- /dev/null +++ b/examples/refresh/pages/index.vue @@ -0,0 +1,220 @@ + + + diff --git a/examples/refresh/public/favicon.ico b/examples/refresh/public/favicon.ico new file mode 100644 index 00000000..b3d1e39f Binary files /dev/null and b/examples/refresh/public/favicon.ico differ diff --git a/examples/refresh/server/api/auth/[...].ts b/examples/refresh/server/api/auth/[...].ts new file mode 100644 index 00000000..8ea20e8f --- /dev/null +++ b/examples/refresh/server/api/auth/[...].ts @@ -0,0 +1,51 @@ +import CredentialsProvider from 'next-auth/providers/credentials' +import GithubProvider from 'next-auth/providers/github' +import { NuxtAuthHandler } from '#auth' + +export default NuxtAuthHandler({ + // TODO: SET A STRONG SECRET, SEE https://sidebase.io/nuxt-auth/configuration/nuxt-auth-handler#secret + secret: process.env.AUTH_SECRET, + // TODO: ADD YOUR OWN AUTHENTICATION PROVIDER HERE, READ THE DOCS FOR MORE: https://sidebase.io/nuxt-auth + providers: [ + // @ts-expect-error You need to use .default here for it to work during SSR. May be fixed via Vite at some point + GithubProvider.default({ + clientId: process.env.GITHUB_CLIENT_ID || 'enter-your-client-id-here', + clientSecret: process.env.GITHUB_CLIENT_SECRET || 'enter-your-client-secret-here', // TODO: Replace this with an env var like "process.env.GITHUB_CLIENT_SECRET". The secret should never end up in your github repository + }), + // @ts-expect-error You need to use .default here for it to work during SSR. May be fixed via Vite at some point + CredentialsProvider.default({ + // The name to display on the sign in form (e.g. 'Sign in with...') + name: 'Credentials', + // The credentials is used to generate a suitable form on the sign in page. + // You can specify whatever fields you are expecting to be submitted. + // e.g. domain, username, password, 2FA token, etc. + // You can pass any HTML attribute to the tag through the object. + credentials: { + username: { label: 'Username', type: 'text', placeholder: '(hint: jsmith)' }, + password: { label: 'Password', type: 'password', placeholder: '(hint: hunter2)' }, + }, + authorize(credentials: any) { + console.warn('ATTENTION: You should replace this with your real providers or credential provider logic! The current setup is not safe') + // You need to provide your own logic here that takes the credentials + // submitted and returns either a object representing a user or value + // that is false/null if the credentials are invalid. + // NOTE: THE BELOW LOGIC IS NOT SAFE OR PROPER FOR AUTHENTICATION! + + const user = { id: '1', name: 'J Smith', username: 'jsmith', password: 'hunter2' } + + if (credentials?.username === user.username && credentials?.password === user.password) { + // Any object returned will be saved in `user` property of the JWT + return user + } + else { + console.error('Warning: Malicious login attempt registered, bad credentials provided') + + // If you return null then an error will be displayed advising the user to check their details. + return null + + // You can also Reject this callback with an Error thus the user will be sent to the error page with the error message as a query parameter + } + }, + }), + ], +}) diff --git a/examples/refresh/server/tsconfig.json b/examples/refresh/server/tsconfig.json new file mode 100644 index 00000000..b9ed69c1 --- /dev/null +++ b/examples/refresh/server/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../.nuxt/tsconfig.server.json" +} diff --git a/examples/refresh/tsconfig.json b/examples/refresh/tsconfig.json new file mode 100644 index 00000000..a746f2a7 --- /dev/null +++ b/examples/refresh/tsconfig.json @@ -0,0 +1,4 @@ +{ + // https://nuxt.com/docs/guide/concepts/typescript + "extends": "./.nuxt/tsconfig.json" +}