1
0
mirror of synced 2026-02-08 06:00:13 -05:00

Compare commits

..

26 Commits

Author SHA1 Message Date
github-actions[bot]
99541848b3 Version Packages (beta) (#4258)
* Version Packages (beta)

* pnpm lock fix

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Siddharth Suresh <siddh.suresh@gmail.com>
2023-11-29 00:21:19 +05:30
Siddharth Suresh
09e0c68db9 Add logic to auto authorize role with usage of redirectAuthenticatedTo (#4257)
* add logic to auto handle role with usage of `redirectAuthenticatedTo`

* Create hot-knives-vanish.md

* fix `globalThis.__BLITZ_GET_RSC_CONTEXT` being overriden

* pnpm lock fix
2023-11-28 17:58:39 +00:00
github-actions[bot]
fb232d126e Version Packages (beta) (#4227)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-10-30 18:48:22 +05:30
Siddharth Suresh
b97366c427 Remove unintended dependency on next-auth (#4235)
* export `next-auth` and all its requirements in a sub-directory

* Create modern-insects-raise.md

* undo changes to `secure-password` adapter

* try another way

* Update .changeset/modern-insects-raise.md

* Update .changeset/modern-insects-raise.md

* patch next-auth
2023-10-30 18:41:44 +05:30
Blitz.js Bot
11eeebee67 (meta) added @potikhanovsergey as contributor 2023-10-25 12:29:05 -04:00
Siddharth Suresh
c89cb943bb Upgrade next, prisma and zod to latest versions (#4237)
* upgrade next, prisma and zod to latest versions

* Create green-years-behave.md
2023-10-24 13:26:40 +00:00
Siddharth Suresh
3bcbad1a91 invoke with RPC Logger (#4229)
* add logging to rsc invoke and decouple auth from rpc again

* implement object chaining

* add `onInvokeError` options to catch errors without manual wrapping

* rename `LoggerOptions` to `RpcLoggerOptions`

* spacing

* fix error typed to `any`

* update class code

* tests working again

* add last test case proving working modal of roles

* Create moody-pandas-do.md

* Apply suggestions from code review

* blitz invoke logger
2023-10-24 18:48:11 +05:30
Siddharth Suresh
98d04ed613 Recipes: Map Repo link to this repository (#4228)
* map repolink of recipies to main repo

* Create pretty-snakes-search.md
2023-10-15 14:21:11 +05:30
Siddharth Suresh
cee2dec179 Authenticate does not work with roles (#4225)
* fix logic to test the role

* add tests

* pnpm lock

* Create afraid-ligers-build.md

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2023-10-05 20:26:42 +05:30
Siddharth Suresh
aec1bb076b blitz-next: Fix next/head warning in app directory (#4176)
* feat: Load Head lazyily using `dynamic`

* feat: upgrate turbo and fix layout.tsx

* fix: pnpm lock version

* Create chatty-scissors-jump.md

* Update .changeset/chatty-scissors-jump.md

* fix: move `dynamic` call to the top of the file

* add loading state to be null and no ssr
2023-10-05 20:12:26 +05:30
Blitz.js Bot
2c72af7175 (meta) added @Zamfi99 as contributor 2023-10-05 10:24:23 -04:00
Zamfira Costin-Andrei
465a5c0720 Fix for Tailwind recipe (#4165)
* Tailwind recipe: fixed tailwind.config.js

* Tailwind recipe: change dependecies to devDependecies

* Update recipes/tailwind/templates/config/tailwind.config.js

* Create neat-gorillas-switch.md

* pnpm lock fix

---------

Co-authored-by: Brandon Bayer <b@bayer.ws>
Co-authored-by: Siddharth Suresh <siddh.suresh@gmail.com>
2023-10-05 14:24:18 +00:00
github-actions[bot]
353af3fae6 Version Packages (beta) (#4216)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-10-03 12:07:42 +05:30
Siddharth Suresh
3ddb57072b Update location of resolve-href in next 13.5.2 (#4222)
* upgrade to next 13.5.2 and update location of internal function

* Create lucky-teachers-sleep.md

* fix bootupMarkers

* fix issues with qm integration test

* Update integration-tests/utils/next-test-utils.ts

* next.js generated stuff

* Update .changeset/lucky-teachers-sleep.md

* remove unnecessary next lints to the integration-tests

* Update main.yml

* Revert "remove unnecessary next lints to the integration-tests"

This reverts commit 3226b2e3ba.
2023-10-03 12:02:46 +05:30
Siddharth Suresh
8477d44aa7 Update Flightcontrol logo formatting 2023-09-19 23:18:53 +05:30
Siddharth Suresh
6802c67809 [Internal] Update Flightcontrol logo (#4220) 2023-09-19 23:00:39 +05:30
Siddharth Suresh
fe8c937d24 Remove rouge console.log from codegen (#4215) 2023-09-11 23:53:47 +05:30
Kevin Østerkilde
30fd613164 feat(cli): remove unnecessary language selector step (#4214) 2023-09-11 19:14:51 +05:30
github-actions[bot]
9a5ce2e8ea Version Packages (beta) (#4212)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-09-06 16:39:31 +05:30
Blitz.js Bot
81290b478c (meta) added @rodobre as contributor 2023-09-06 06:54:22 -04:00
rodobre
19898a4886 Fix for tslog error logging (#4208)
* Added: Fix for tslog error logging

* Create nervous-shrimps-serve.md

---------

Co-authored-by: Siddharth Suresh <siddh.suresh@gmail.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2023-09-06 10:54:17 +00:00
David
6811eab1aa Add .tsx & .jsx file extensions for resolvers (#4209)
Co-authored-by: Siddharth Suresh <siddh.suresh@gmail.com>
2023-09-06 16:16:19 +05:30
Siddharth Suresh
022392c123 fixes: Blitz template (#4211) 2023-09-05 19:37:55 +05:30
Siddharth Suresh
e3522d65ef sponser: update asset names 2023-08-25 12:30:58 +05:30
Siddharth Suresh
cb1600a821 sponsor: update Byteflow Logo 2023-08-25 12:23:12 +05:30
github-actions[bot]
e1bffdf3d6 Version Packages (beta) (#4197)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Siddharth Suresh <siddh.suresh@gmail.com>
2023-08-17 23:41:49 +05:30
174 changed files with 3492 additions and 1288 deletions

View File

@@ -3975,6 +3975,35 @@
"doc",
"code"
]
},
{
"login": "rodobre",
"name": "rodobre",
"avatar_url": "https://avatars.githubusercontent.com/u/52138375?v=4",
"profile": "https://github.com/rodobre",
"contributions": [
"doc",
"code"
]
},
{
"login": "Zamfi99",
"name": "Zamfira Costin-Andrei",
"avatar_url": "https://avatars.githubusercontent.com/u/19189337?v=4",
"profile": "https://github.com/Zamfi99",
"contributions": [
"doc",
"code"
]
},
{
"login": "potikhanovsergey",
"name": "Sergey",
"avatar_url": "https://avatars.githubusercontent.com/u/71494201?v=4",
"profile": "https://github.com/potikhanovsergey",
"contributions": [
"doc"
]
}
],
"contributorsPerLine": 7,

View File

@@ -0,0 +1,6 @@
---
"@blitzjs/auth": patch
"blitz": patch
---
Fix bug that did not allow `Page.authenicate = {role: "" }` to correctly work

View File

@@ -0,0 +1,6 @@
---
"@blitzjs/next": patch
"blitz": patch
---
blitz-next: Fix `next/head` used in app directory warning

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/generator": patch
---
Upgrade next, prisma and zod to latest versions in a newly created app

View File

@@ -0,0 +1,6 @@
---
"@blitzjs/auth": patch
"blitz": patch
---
Automatically authorize role with usage of `redirectAuthenticatedTo` in `useAuthenticatedBlitzContext` utility

View File

@@ -0,0 +1,6 @@
---
"blitz": patch
---
- Removes language selection step from `blitz new` menu
- Make `formik` the default/recommended form library

View File

@@ -0,0 +1,10 @@
---
"@blitzjs/auth": patch
"@blitzjs/next": major
"@blitzjs/rpc": patch
"blitz": patch
---
⚠️ Breaking Change:
Next.js version 13.5 or above is now required to use `@blitzjs/next`
Fix `Error: Cannot find module 'next/dist/shared/lib/router/utils/resolve-href'` by updating the location of next.js internal function.

View File

@@ -0,0 +1,13 @@
---
"@blitzjs/auth": patch
"blitz": patch
---
Remove unintended dependency on next-auth by removing it from the core build of @blitzjs/auth
⚠️ Breaking Change for current users of `withNextAuthAdapter`
Update your import in `next.config.js` in the following way
```diff
-const { withNextAuthAdapter } = require("@blitzjs/auth")
+const { withNextAuthAdapter } = require("@blitzjs/auth/next-auth")

View File

@@ -0,0 +1,9 @@
---
"@blitzjs/auth": patch
"@blitzjs/rpc": patch
"blitz": patch
---
- Introduce Blitz RPC's logging system to the `invoke` function which is the recommended way to call resolvers in nextjs `app` directory's react server components.
- This refactor also removes the re-introduced dependency between `blitz-auth` and `blitz-rpc`, allowing independent usage of `blitz-rpc`

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/recipe-tailwind": patch
---
Change tailwind recipe to install dependencies as devDependencies

View File

@@ -0,0 +1,6 @@
---
"@blitzjs/rpc": patch
"blitz": patch
---
Fix for tslog error `TypeError: Cannot read properties of undefined (reading 'map')` while using custom errors.

View File

@@ -0,0 +1,6 @@
---
"@blitzjs/rpc": patch
"blitz": patch
---
Allow `.tsx` & `.jsx` file extensions to be used for resolvers

View File

@@ -1,6 +0,0 @@
---
"@blitzjs/auth": major
"blitz": patch
---
Migrate `next-auth` adapter to use `@auth/core`

View File

@@ -53,6 +53,7 @@
"changesets": [
"afraid-dancers-juggle",
"afraid-ears-repair",
"afraid-ligers-build",
"big-boats-lay",
"big-phones-bow",
"big-turtles-tease",
@@ -72,12 +73,15 @@
"calm-tomatoes-drive",
"chatty-fireants-leave",
"chatty-gifts-whisper",
"chatty-scissors-jump",
"chilled-carrots-own",
"chilly-candles-care",
"chilly-jeans-fix",
"chilly-nails-nail",
"clean-hats-pump",
"clean-hounds-laugh",
"clean-walls-wink",
"clever-hornets-talk",
"clever-radios-lie",
"cool-doors-invent",
"cool-horses-check",
@@ -124,6 +128,7 @@
"four-meals-fry",
"four-radios-tickle",
"four-sheep-judge",
"fresh-camels-return",
"fresh-crews-chew",
"funny-cups-pay",
"fuzzy-bees-warn",
@@ -146,6 +151,7 @@
"great-terms-rescue",
"green-papayas-do",
"green-pillows-hammer",
"green-years-behave",
"happy-bees-lick",
"happy-hotels-visit",
"happy-paws-join",
@@ -159,6 +165,7 @@
"honest-comics-vanish",
"hot-cups-rhyme",
"hot-drinks-approve",
"hot-knives-vanish",
"hungry-baboons-swim",
"hungry-pens-collect",
"itchy-cups-double",
@@ -176,6 +183,7 @@
"lemon-teachers-jam",
"light-donkeys-double",
"light-squids-draw",
"little-cycles-hang",
"little-pears-ring",
"long-bees-hope",
"long-dancers-jog",
@@ -185,23 +193,29 @@
"lovely-colts-share",
"lucky-cows-try",
"lucky-months-guess",
"lucky-teachers-sleep",
"lucky-years-turn",
"many-fans-fetch",
"mean-ears-speak",
"mean-gorillas-reply",
"modern-cameras-pull",
"modern-games-dream",
"modern-insects-raise",
"modern-ligers-behave",
"moody-bags-walk",
"moody-crews-travel",
"moody-pandas-do",
"moody-spoons-rhyme",
"moody-squids-cheer",
"nasty-suns-wash",
"neat-gorillas-switch",
"nervous-beds-travel",
"nervous-dolls-rule",
"nervous-shrimps-serve",
"new-coats-turn",
"new-olives-protect",
"nice-boxes-travel",
"nice-cats-lay",
"nice-deers-dream",
"nice-starfishes-live",
"nine-bags-rhyme",
@@ -233,9 +247,11 @@
"poor-walls-relax",
"popular-teachers-pay",
"pretty-games-march",
"pretty-snakes-search",
"purple-donkeys-smash",
"purple-jars-begin",
"purple-singers-greet",
"quick-crews-occur",
"quick-cycles-confess",
"quick-dots-fetch",
"quiet-feet-travel",
@@ -250,6 +266,7 @@
"rotten-rocks-remember",
"rude-trainers-visit",
"serious-mugs-leave",
"shaggy-boxes-exercise",
"shaggy-carpets-brake",
"sharp-falcons-begin",
"sharp-olives-sip",

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/recipe-next-ui": patch
---
Add `framer-motion` as a dependency of `next-ui`

View File

@@ -0,0 +1,5 @@
---
"blitz": patch
---
Remove rouge `console.log` during start

View File

@@ -0,0 +1,9 @@
---
"@blitzjs/next": patch
"blitz": patch
"@blitzjs/generator": patch
---
- Updates `ts-log` peer dependency to `4.9.0`
- Removes `javascript` from `blitz new` menu
- Hot Fix the `Update Schema` when using blitz generator

View File

@@ -23,7 +23,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@v2
with:
node-version: 16
node-version: 18
cache: "pnpm"
- name: Install dependencies
run: pnpm install --frozen-lockfile
@@ -44,7 +44,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@v2
with:
node-version: 16
node-version: 18
cache: "pnpm"
- run: pnpm install --frozen-lockfile
- name: Build
@@ -62,7 +62,7 @@ jobs:
- windows-latest
fail-fast: false
env:
NODE_VERSION: 16
NODE_VERSION: 18
steps:
- name: Checkout
uses: actions/checkout@v3
@@ -75,7 +75,7 @@ jobs:
- name: Setup node@16
uses: actions/setup-node@v2
with:
node-version: 16
node-version: 18
cache: "pnpm"
- name: Install dependencies
@@ -111,7 +111,7 @@ jobs:
echo "folders=$folders" >> $GITHUB_OUTPUT
Integration-Tests:
name: "Integration Test: ${{matrix.folder}} @ ${{ matrix.os }} "
name: "Integration Test: ${{matrix.folder}} @ ${{ matrix.os }}"
needs: [find-integration-tests]
strategy:
matrix:
@@ -124,32 +124,39 @@ jobs:
steps:
- run: echo ${{matrix.folder}}
- name: Checkout
if: matrix.folder != 'next-13-app-dir' || matrix.os != 'windows-latest'
uses: actions/checkout@v3
- name: Setup PNPM
if: matrix.folder != 'next-13-app-dir' || matrix.os != 'windows-latest'
uses: pnpm/action-setup@v2.2.4
with:
version: 8.6.5
- name: Setup node@18
if: matrix.folder != 'next-13-app-dir' || matrix.os != 'windows-latest'
uses: actions/setup-node@v2
with:
node-version: 18
cache: "pnpm"
- name: Install dependencies
if: matrix.folder != 'next-13-app-dir' || matrix.os != 'windows-latest'
run: pnpm install --frozen-lockfile
shell: bash
- name: Install playwright
if: matrix.folder != 'next-13-app-dir' || matrix.os != 'windows-latest'
run: |
pnpx playwright@1.28.0 install --with-deps
shell: bash
- name: Build
if: matrix.folder != 'next-13-app-dir' || matrix.os != 'windows-latest'
run: pnpm build
shell: bash
- name: Test Packages
if: matrix.folder != 'next-13-app-dir' || matrix.os != 'windows-latest'
run: pnpm test -- --filter=./integration-tests/${{matrix.folder}}
shell: bash

View File

@@ -6,7 +6,7 @@
<img alt="" src="https://img.shields.io/badge/Join%20our%20community-6700EB.svg?style=for-the-badge&labelColor=000000&logoWidth=20&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAQ9SURBVHgB7d3dVdtAEIbhcSpICUoH0IEogQqSVBBSAU4FSSpIOoAORAfQgSghHXzZ1U/YcMD4R9rZmf2ec3y448LyiNf27iLiGIAmPLrweC9Un3DhrzG6EarLNP09nlwJ1SOZ/lQr5N80/S/p2QMVCBf5N17XCfm1Y/rBHqjAG9PPHvBsz+mf9WAP+HLA9M/YA14cOP2payH7jpj+VCtk1wnTP+vj7xCy6cTpn7EHLMLp059iD1iD8eveJbVCNsSLheX1YA/YgOWnf8YeKB3Wmf7Ud6Fy4f/FHmtpxbl3YlC4MJ/Cj0bWdwPnPbARg+L0S54XQHS32WwuxClzd4CM0z9rPfeAuTtA5ulPXYQ7wZ04Y+oOoDD9KZc9YOoOoDj9s4dwFzgXR6w1wIPoOvPWA9buAHEJ173o3gWiy3AnuBUHLEbgmYwvAk1/wuM8vAgexThzbwPDkx7/DHwVXfFOxP2GmsKd4Ab6zPeAyU8CI7AHFmH2BRCBPXAyk18GzUrqAXCTiR4ssyj0VFw/oCU8+e+RZ33AWz6KMaYbIIWxB+JSLs1bsbkeMN0AqakHvoku9oA2sAfqBvbAQdw0QArsgb25aYBUQT3QgT2gB+yBuqGcHij2UCqXDZACe2Anlw2QYg/QAOyBuoE98CL3DZDCuK4/rh/Q7oGL6U+TOvcNkJoijN8X1C48+T+g75eQDrAH/qmqAVJgDwyqaoAUe4AGYA/UDZX3QLUNkEIZPRCd5+6BahsgVUgPROwBTSijB7jpVAvGHriHvmw9wAZ4BpX1ABvgmakHtPcbRuwBTWAPULgAV9D/jKDY9YRvwvgEaurD44uQHvAol7qBW7WKluVtIHiUS7GyvA0s6CiXDnxrpQfsgbqBS7GKk/2jYHCrVlGyfxTMrVo0ALdq1Q3sgSKofh0M9oA61a+D2QM0AHugbmAPqClmSRjK2apVVQ8UsySsoK1aHdgDesCtWnUDeyCrIpeFg1u3sylyWTi3btMA7IG6gT2wuuK3hoE9sKrit4YVslWLPaAN7IG6ocKt2zmY2h4O9sDiTG0PZw/QANy6XTewBxZj9ogYVHy025LMHhEz9cBn0We6B0yfERReBLfhx0/R1YQHPx/QBPbA0VwcEwf2wNFcHBPHHjiem3MC2QPHcXdSaJjA+KfgTPQ8hhfjBzHC40mhlzJ+Xq9lK4a4PCs43AVaGTed5mZq+iOXZwWHi3AnOj2wFWNcnxYe7gTxLtBKHuamP/J+Wnh8a5irB7ZC5Yk9gPX1QuXC+usHWqGyhYvUYR0a7zboUOFCNVhnk0krZAOW7wFOvzXhom2xnEbIHizTA1wEYhWW6YFGyC6c1gOcfg9wfA80Qj7g8B7g9HuCww+haIR8wf49wOn3Cvv9k8tGyC/s7gFOv3fY3QONkH+v9MBWqB7PeqDn9FcIT//kcitUn6kHOu/T/xfWzlQy3dEHhwAAAABJRU5ErkJggg==">
</a>
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
<a aria-label="All Contributors" href="#contributors-"><img alt="" src="https://img.shields.io/badge/all_contributors-419-17BB8A.svg?style=for-the-badge&labelColor=000000"></a>
<a aria-label="All Contributors" href="#contributors-"><img alt="" src="https://img.shields.io/badge/all_contributors-422-17BB8A.svg?style=for-the-badge&labelColor=000000"></a>
<!-- ALL-CONTRIBUTORS-BADGE:END -->
<a aria-label="License" href="https://github.com/blitz-js/blitz/blob/main/LICENSE">
<img alt="" src="https://img.shields.io/npm/l/blitz.svg?style=for-the-badge&labelColor=000000&color=blue">
@@ -96,7 +96,7 @@ Your financial contributions help ensure Blitz continues to be developed and mai
</a></td>
<td>
<a aria-label="Byteflow" href="https://byteflow.app/?ref=blitzjs">
<img alt="" src="https://raw.githubusercontent.com/blitz-js/blitz/main/assets/Byteflow.png" width="70px">
<img alt="" src="https://raw.githubusercontent.com/blitz-js/blitz/main/assets/byteflow.png" width="70px">
</a>
</td>
</tr>
@@ -126,9 +126,11 @@ Your financial contributions help ensure Blitz continues to be developed and mai
<table>
<tr>
<td>
<a aria-label="Flightcontrol" href="https://www.flightcontrol.dev?ref=blitzjs">
<img alt="" src="https://raw.githubusercontent.com/blitz-js/blitz/main/assets/flightcontrol.png" width="400px">
</a>
</td>
</tr>
</table>
@@ -739,6 +741,11 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
<td align="center"><a href="jayu.dev"><img src="https://avatars.githubusercontent.com/u/11561585?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jakub Mazurek</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=jayu" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=jayu" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/maciej-ka"><img src="https://avatars.githubusercontent.com/u/5403694?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Maciej Kasprzyk</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=maciej-ka" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=maciej-ka" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/justinsmid"><img src="https://avatars.githubusercontent.com/u/34271675?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Justin Smid</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=justinsmid" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=justinsmid" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/rodobre"><img src="https://avatars.githubusercontent.com/u/52138375?v=4?s=100" width="100px;" alt=""/><br /><sub><b>rodobre</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=rodobre" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=rodobre" title="Code">💻</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/Zamfi99"><img src="https://avatars.githubusercontent.com/u/19189337?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Zamfira Costin-Andrei</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Zamfi99" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=Zamfi99" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/potikhanovsergey"><img src="https://avatars.githubusercontent.com/u/71494201?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Sergey</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=potikhanovsergey" title="Documentation">📖</a></td>
</tr>
</table>

View File

@@ -1,5 +1,68 @@
# next-blitz-auth
## 0.1.1-beta.12
### Patch Changes
- Updated dependencies [09e0c68db]
- @blitzjs/auth@2.0.0-beta.36
- blitz@2.0.0-beta.36
- @blitzjs/rpc@2.0.0-beta.36
- @blitzjs/next@2.0.0-beta.36
- @blitzjs/config@2.0.0-beta.36
## 0.1.1-beta.11
### Patch Changes
- Updated dependencies [cee2dec17]
- Updated dependencies [aec1bb076]
- Updated dependencies [b97366c42]
- Updated dependencies [3bcbad1a9]
- @blitzjs/auth@2.0.0-beta.35
- blitz@2.0.0-beta.35
- @blitzjs/next@2.0.0-beta.35
- @blitzjs/rpc@2.0.0-beta.35
- @blitzjs/config@2.0.0-beta.35
## 0.1.1-beta.10
### Patch Changes
- Updated dependencies [30fd61316]
- Updated dependencies [3ddb57072]
- Updated dependencies [fe8c937d2]
- blitz@2.0.0-beta.34
- @blitzjs/auth@2.0.0-beta.34
- @blitzjs/next@2.0.0-beta.34
- @blitzjs/rpc@2.0.0-beta.34
- @blitzjs/config@2.0.0-beta.34
## 0.1.1-beta.9
### Patch Changes
- Updated dependencies [19898a488]
- Updated dependencies [6811eab1a]
- Updated dependencies [022392c12]
- @blitzjs/rpc@2.0.0-beta.33
- blitz@2.0.0-beta.33
- @blitzjs/next@2.0.0-beta.33
- @blitzjs/auth@2.0.0-beta.33
- @blitzjs/config@2.0.0-beta.33
## 0.1.1-beta.8
### Patch Changes
- Updated dependencies [82649f341]
- Updated dependencies [8b01175b4]
- blitz@2.0.0-beta.32
- @blitzjs/next@2.0.0-beta.32
- @blitzjs/auth@2.0.0-beta.32
- @blitzjs/rpc@2.0.0-beta.32
- @blitzjs/config@2.0.0-beta.32
## 0.1.1-beta.7
### Patch Changes

View File

@@ -1,4 +1,4 @@
import {useAuthenticatedBlitzContext} from "@blitzjs/auth"
import {useAuthenticatedBlitzContext} from "../../src/blitz-server"
export default async function RootLayout({children}: {children: React.ReactNode}) {
await useAuthenticatedBlitzContext({

View File

@@ -9,7 +9,6 @@ export default async function Home() {
redirectTo: "/auth/login",
})
const user = await invoke(getCurrentUser, null)
console.log("user", user)
return (
<div
style={{

View File

@@ -1,6 +1,6 @@
{
"name": "next-blitz-auth",
"version": "0.1.1-beta.7",
"version": "0.1.1-beta.12",
"private": true,
"scripts": {
"blitz:dev": "next dev",
@@ -9,17 +9,17 @@
"lint": "next lint"
},
"dependencies": {
"@blitzjs/auth": "2.0.0-beta.31",
"@blitzjs/config": "2.0.0-beta.31",
"@blitzjs/next": "2.0.0-beta.31",
"@blitzjs/rpc": "2.0.0-beta.31",
"@blitzjs/auth": "2.0.0-beta.36",
"@blitzjs/config": "2.0.0-beta.36",
"@blitzjs/next": "2.0.0-beta.36",
"@blitzjs/rpc": "2.0.0-beta.36",
"@hookform/error-message": "2.0.0",
"@hookform/resolvers": "2.9.10",
"@prisma/client": "^4.5.0",
"@tanstack/react-query": "4.0.10",
"blitz": "2.0.0-beta.31",
"blitz": "2.0.0-beta.36",
"flatted": "3.2.7",
"next": "13.3.0",
"next": "13.5.2",
"prisma": "^4.5.0",
"react": "18.2.0",
"react-dom": "18.2.0",

View File

@@ -13,7 +13,14 @@ const {api, getBlitzContext, useAuthenticatedBlitzContext, invoke} = setupBlitzS
storage: PrismaStorage(db),
isAuthorized: simpleRolesIsAuthorized,
}),
RpcServerPlugin({}),
RpcServerPlugin({
logging: {
disablelevel: "debug",
},
onInvokeError(error) {
console.log("onInvokeError", error)
},
}),
],
logger: BlitzLogger({}),
})

View File

@@ -23,15 +23,15 @@
]
},
"dependencies": {
"@blitzjs/auth": "2.0.0-beta.31",
"@blitzjs/config": "2.0.0-beta.31",
"@blitzjs/next": "2.0.0-beta.31",
"@blitzjs/rpc": "2.0.0-beta.31",
"@blitzjs/auth": "2.0.0-beta.36",
"@blitzjs/config": "2.0.0-beta.36",
"@blitzjs/next": "2.0.0-beta.36",
"@blitzjs/rpc": "2.0.0-beta.36",
"@hookform/error-message": "2.0.0",
"@hookform/resolvers": "2.9.10",
"@prisma/client": "4.6.1",
"blitz": "2.0.0-beta.31",
"next": "13.3.0",
"blitz": "2.0.0-beta.36",
"next": "13.5.2",
"openid-client": "5.2.1",
"prisma": "4.6.1",
"react": "18.2.0",

View File

@@ -1,3 +1,4 @@
const { withNextAuthAdapter } = require("@blitzjs/auth/next-auth")
const { withBlitz } = require("@blitzjs/next")
/**
@@ -10,4 +11,4 @@ const config = {
},
}
module.exports = withBlitz(config)
module.exports = withBlitz(withNextAuthAdapter(config))

View File

@@ -24,16 +24,16 @@
]
},
"dependencies": {
"@auth/core": "0.10.0",
"@blitzjs/auth": "2.0.0-beta.31",
"@blitzjs/config": "2.0.0-beta.31",
"@blitzjs/next": "2.0.0-beta.31",
"@blitzjs/rpc": "2.0.0-beta.31",
"@blitzjs/auth": "2.0.0-beta.36",
"@blitzjs/config": "2.0.0-beta.36",
"@blitzjs/next": "2.0.0-beta.36",
"@blitzjs/rpc": "2.0.0-beta.36",
"@hookform/error-message": "2.0.0",
"@hookform/resolvers": "2.9.10",
"@prisma/client": "4.6.1",
"blitz": "2.0.0-beta.31",
"next": "13.3.0",
"blitz": "2.0.0-beta.36",
"next": "13.5.2",
"next-auth": "4.18.7",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0",

View File

@@ -1,6 +1,6 @@
import { api } from "src/blitz-server"
import GithubProvider from "@auth/core/providers/github"
import { AuthAdapter } from "@blitzjs/auth/adapters/authjs"
import GithubProvider from "next-auth/providers/github"
import { NextAuthAdapter } from "@blitzjs/auth/next-auth"
import db, { User } from "db"
import { Role } from "types"
@@ -13,23 +13,20 @@ const providers = [
]
export default api(
AuthAdapter({
NextAuthAdapter({
successRedirectUrl: "/",
errorRedirectUrl: "/error",
providers,
trustHost: true,
secret: process.env.AUTH_SECRET,
callback: async (user, account, profile, session) => {
console.log("USER SIDE PROFILE_DATA", { user, account, profile })
let newUser: User
if (!user) throw new Error("No user found")
try {
newUser = await db.user.findFirstOrThrow({ where: { name: { equals: user.name } } })
} catch (e) {
newUser = await db.user.create({
data: {
email: user.email ?? "",
name: user.name ?? "",
email: user.email as string,
name: user.name as string,
role: "USER",
},
})

View File

@@ -5,6 +5,7 @@ import { useCurrentUser } from "src/users/hooks/useCurrentUser"
import logout from "src/auth/mutations/logout"
import { useMutation } from "@blitzjs/rpc"
import { BlitzPage } from "@blitzjs/next"
import { Routes } from ".blitz"
import styles from "src/styles/Home.module.css"
/*
@@ -31,8 +32,6 @@ const UserInfo = () => {
User id: <code>{currentUser.id}</code>
<br />
User role: <code>{currentUser.role}</code>
<br />
User email: <code>{currentUser.email}</code>
</div>
</>
)
@@ -45,11 +44,11 @@ const UserInfo = () => {
<Link href={"/login"} className={styles.loginButton}>
<strong>Login</strong>
</Link>
<a href="/api/auth/github/signin">
<p className="button small">
<Link href="/api/auth/github/login" passHref legacyBehavior>
<a className="button small">
<strong>Sign in with GitHub</strong>
</p>
</a>
</a>
</Link>
</>
)
}
@@ -80,6 +79,8 @@ const Home: BlitzPage = () => {
<h1>Your database & authentication is ready. Try it by signing up.</h1>
{/* Auth */}
<div className={styles.buttonContainer}>
<Suspense fallback="Loading...">
<UserInfo />

View File

@@ -2,7 +2,6 @@ import { useQuery } from "@blitzjs/rpc"
import getCurrentUser from "src/users/queries/getCurrentUser"
export const useCurrentUser = () => {
console.log("useCurrentUser")
const [user] = useQuery(getCurrentUser, null)
return user
}

View File

@@ -16,17 +16,17 @@
"schema": "./db/schema.prisma"
},
"dependencies": {
"@blitzjs/auth": "2.0.0-beta.31",
"@blitzjs/config": "2.0.0-beta.31",
"@blitzjs/next": "2.0.0-beta.31",
"@blitzjs/rpc": "2.0.0-beta.31",
"@blitzjs/auth": "2.0.0-beta.36",
"@blitzjs/config": "2.0.0-beta.36",
"@blitzjs/next": "2.0.0-beta.36",
"@blitzjs/rpc": "2.0.0-beta.36",
"@prisma/client": "4.6.1",
"@types/jest": "29.2.2",
"@types/passport-twitter": "1.0.37",
"blitz": "2.0.0-beta.31",
"blitz": "2.0.0-beta.36",
"jest": "29.3.0",
"jest-environment-jsdom": "29.3.0",
"next": "13.3.0",
"next": "13.5.2",
"passport-mock-strategy": "2.0.0",
"passport-twitter": "1.0.4",
"prisma": "4.6.1",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

BIN
assets/byteflow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 87 KiB

View File

@@ -17,16 +17,16 @@
"prisma:studio": "prisma studio"
},
"dependencies": {
"@blitzjs/auth": "2.0.0-beta.31",
"@blitzjs/config": "2.0.0-beta.31",
"@blitzjs/next": "2.0.0-beta.31",
"@blitzjs/rpc": "2.0.0-beta.31",
"@blitzjs/auth": "2.0.0-beta.36",
"@blitzjs/config": "2.0.0-beta.36",
"@blitzjs/next": "2.0.0-beta.36",
"@blitzjs/rpc": "2.0.0-beta.36",
"@hookform/error-message": "2.0.0",
"@hookform/resolvers": "2.9.10",
"@prisma/client": "4.6.1",
"blitz": "2.0.0-beta.31",
"blitz": "2.0.0-beta.36",
"delay": "5.0.0",
"next": "13.3.0",
"next": "13.5.2",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0",

View File

@@ -1,6 +1,10 @@
import {Ctx} from "blitz"
import db from "../../db"
const getRand = () => Math.random().toString(36).substring(7)
export default async function login(_: any, ctx: Ctx) {
await ctx.session.$create({userId: 1, role: "USER"})
const user = await db.user.create({data: {email: `${getRand()}@example.com`}})
await ctx.session.$create({userId: user.id, role: "USER"})
return true
}

View File

@@ -0,0 +1,37 @@
import {useMutation, useQuery} from "@blitzjs/rpc"
import {BlitzPage} from "@blitzjs/next"
import logout from "../mutations/logout"
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
import {Suspense} from "react"
function Content() {
const [result] = useQuery(getAuthenticatedBasic, undefined)
const [logoutMutation] = useMutation(logout)
return (
<div>
<div id="content">{result}</div>
<button
id="logout"
onClick={async () => {
await logoutMutation()
}}
>
logout
</button>
</div>
)
}
const Authenticate: BlitzPage = () => {
return (
<div id="page">
<Suspense fallback={"Loading..."}>
<Content />
</Suspense>
</div>
)
}
Authenticate.authenticate = {role: "USER", redirectTo: "/noauth-query"}
export default Authenticate

View File

@@ -0,0 +1,37 @@
import {useMutation, useQuery} from "@blitzjs/rpc"
import {BlitzPage} from "@blitzjs/next"
import logout from "../mutations/logout"
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
import {Suspense} from "react"
function Content() {
const [result] = useQuery(getAuthenticatedBasic, undefined)
const [logoutMutation] = useMutation(logout)
return (
<div>
<div id="content">{result}</div>
<button
id="logout"
onClick={async () => {
await logoutMutation()
}}
>
logout
</button>
</div>
)
}
const Authenticate: BlitzPage = () => {
return (
<div id="page">
<Suspense fallback={"Loading..."}>
<Content />
</Suspense>
</div>
)
}
Authenticate.authenticate = {role: "ADMIN", redirectTo: "/noauth-query"}
export default Authenticate

View File

@@ -0,0 +1,37 @@
import {useMutation, useQuery} from "@blitzjs/rpc"
import {BlitzPage} from "@blitzjs/next"
import logout from "../mutations/logout"
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
import {Suspense} from "react"
function Content() {
const [result] = useQuery(getAuthenticatedBasic, undefined)
const [logoutMutation] = useMutation(logout)
return (
<div>
<div id="content">{result}</div>
<button
id="logout"
onClick={async () => {
await logoutMutation()
}}
>
logout
</button>
</div>
)
}
const Authenticate: BlitzPage = () => {
return (
<div id="page">
<Suspense fallback={"Loading..."}>
<Content />
</Suspense>
</div>
)
}
Authenticate.authenticate = {role: "USER"}
export default Authenticate

View File

@@ -0,0 +1,37 @@
import {useMutation, useQuery} from "@blitzjs/rpc"
import {BlitzPage} from "@blitzjs/next"
import logout from "../mutations/logout"
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
import {Suspense} from "react"
function Content() {
const [result] = useQuery(getAuthenticatedBasic, undefined)
const [logoutMutation] = useMutation(logout)
return (
<div>
<div id="content">{result}</div>
<button
id="logout"
onClick={async () => {
await logoutMutation()
}}
>
logout
</button>
</div>
)
}
const Authenticate: BlitzPage = () => {
return (
<div id="page">
<Suspense fallback={"Loading..."}>
<Content />
</Suspense>
</div>
)
}
Authenticate.authenticate = {role: "ADMIN"}
export default Authenticate

View File

@@ -11,39 +11,12 @@ import {
import webdriver from "../../utils/next-webdriver"
let app: any
let appPort: number = 3000
let appPort: number
let mode: "dev" | "server" = "dev"
const runTests = () => {
describe("Auth", () => {
/* TODO - Add a non flaky Integration Test for custom plugin
describe("custom plugin", () => {
it("custom plugin - events", async () => {
const browser = await webdriver(appPort, "/custom-plugin")
let text = await browser.elementByCss("#page").text()
await waitFor(250)
text = await browser.elementByCss("#page").text()
expect(text).toBe("Custom plugin Session Created")
await waitFor(3000)
text = await browser.elementByCss("#page").text()
expect(text).toBe("Custom plugin RPC Error")
if (browser) {
await browser.close()
}
})
it("custom plugin - middleware", async () => {
const browser = await webdriver(appPort, "/custom-plugin")
await waitFor(100)
let text = await browser.elementByCss("#before-req").text()
expect(text).toBe("customHeaderValue")
await waitFor(2000)
text = await browser.elementByCss("#before-res").text()
expect(text).toBe("55")
if (browser) {
await browser.close()
}
})
})
*/
describe("unauthenticated", () => {
it("should render result for open query", async () => {
const browser = await webdriver(appPort, "/noauth-query")
@@ -58,7 +31,11 @@ const runTests = () => {
const browser = await webdriver(appPort, "/authenticated-query")
await browser.waitForElementByCss("#error")
let text = await browser.elementByCss("#error").text()
expect(text).toMatch(/AuthenticationError/)
if (mode === "server") {
expect(text).toMatch(/AuthenticationError/)
} else {
expect(text).toContain("Error")
}
if (browser) await browser.close()
})
@@ -70,6 +47,14 @@ const runTests = () => {
if (browser) await browser.close()
})
it("Page.authenticate = {role} should work ", async () => {
const browser = await webdriver(appPort, "/page-dot-authenticate-role")
await browser.waitForElementByCss("#error")
let text = await browser.elementByCss("#error").text()
expect(text).toMatch(/AuthenticationError/)
if (browser) await browser.close()
})
it("should render error for protected layout", async () => {
const browser = await webdriver(appPort, "/layout-authenticate")
await browser.waitForElementByCss("#error")
@@ -120,18 +105,36 @@ const runTests = () => {
await waitFor(200)
await browser.waitForElementByCss("#error")
text = await browser.elementByCss("#error").text()
expect(text).toMatch(/AuthenticationError/)
if (mode === "server") {
expect(text).toMatch(/AuthenticationError/)
} else {
expect(text).toContain("Error")
}
if (browser) await browser.close()
})
it("Page.authenticate = {redirect} should work ", async () => {
// Login
it("Page.authenticate = {role} should throw authentication error ", async () => {
let browser = await webdriver(appPort, "/login")
await waitFor(200)
await browser.elementByCss("#login").click()
await waitFor(200)
await browser.eval(`window.location = "/page-dot-authenticate-role"`)
await browser.waitForElementByCss("#error")
let text = await browser.elementByCss("#error").text()
expect(text).toMatch(/AuthenticationError/)
if (browser) await browser.close()
})
await browser.eval(`window.location = "/page-dot-authenticate-redirect"`)
it("Page.authenticate = {role: 'custom'} should work ", async () => {
let browser = await webdriver(appPort, "/page-dot-authenticate-role-working")
await browser.waitForElementByCss("#content")
let text = await browser.elementByCss("#content").text()
expect(text).toMatch(/authenticated-basic-result/)
if (browser) await browser.close()
})
it("Page.authenticate = {redirect} should work ", async () => {
let browser = await webdriver(appPort, "/page-dot-authenticate-redirect")
await browser.waitForElementByCss("#content")
let text = await browser.elementByCss("#content").text()
expect(text).toMatch(/authenticated-basic-result/)
@@ -142,14 +145,26 @@ const runTests = () => {
if (browser) await browser.close()
})
it("Layout.authenticate = {redirect} should work ", async () => {
// Login
it("Page.authenticate = {role: 'custom', redirect: 'url'} should work ", async () => {
let browser = await webdriver(appPort, "/login")
await waitFor(200)
await browser.elementByCss("#login").click()
await waitFor(200)
await browser.eval(`window.location = "/page-dot-authenticate-role-redirect"`)
await browser.waitForElementByCss("#content")
expect(await browser.url()).toMatch(/\/noauth-query/)
if (browser) await browser.close()
})
await browser.eval(`window.location = "/layout-authenticate-redirect"`)
it("Page.authenticate = {role: 'custom', redirect: 'url'} should stay ", async () => {
let browser = await webdriver(appPort, "/page-dot-authenticate-role-redirect-stay")
await browser.waitForElementByCss("#content")
expect(await browser.url()).toMatch(/\/page-dot-authenticate-role-redirect-stay/)
if (browser) await browser.close()
})
it("Layout.authenticate = {redirect} should work ", async () => {
let browser = await webdriver(appPort, "/layout-authenticate-redirect")
await browser.waitForElementByCss("#content")
let text = await browser.elementByCss("#content").text()
expect(text).toMatch(/authenticated-basic-result/)
@@ -262,8 +277,9 @@ const runTests = () => {
describe("Auth Tests", () => {
describe("dev mode", () => {
beforeAll(async () => {
mode = "dev"
try {
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
appPort = await findPort()
app = await blitzLaunchApp(appPort, {cwd: process.cwd()})
} catch (error) {
@@ -276,6 +292,7 @@ describe("Auth Tests", () => {
describe("server mode", () => {
beforeAll(async () => {
mode = "server"
try {
await runBlitzCommand(["prisma", "generate"])
await runBlitzCommand(["prisma", "migrate", "deploy"])

View File

@@ -17,13 +17,13 @@
"prisma:studio": "prisma studio"
},
"dependencies": {
"@blitzjs/auth": "2.0.0-beta.31",
"@blitzjs/config": "2.0.0-beta.31",
"@blitzjs/next": "2.0.0-beta.31",
"@blitzjs/auth": "2.0.0-beta.36",
"@blitzjs/config": "2.0.0-beta.36",
"@blitzjs/next": "2.0.0-beta.36",
"@prisma/client": "4.6.1",
"blitz": "2.0.0-beta.31",
"blitz": "2.0.0-beta.36",
"lowdb": "3.0.0",
"next": "13.3.0",
"next": "13.5.2",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0",

View File

@@ -14,7 +14,7 @@ import fetch from "node-fetch"
import {fromBase64} from "b64-lite"
let app: any
let appPort: number = 3000
let appPort: number
const HEADER_CSRF = "anti-csrf"
const COOKIE_PUBLIC_DATA_TOKEN = "auth-tests-cookie-prefix_sPublicDataToken"
const COOKIE_SESSION_TOKEN = "auth-tests-cookie-prefix_sSessionToken"
@@ -132,7 +132,7 @@ describe("Auth Tests", () => {
describe("dev mode", async () => {
beforeAll(async () => {
try {
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
appPort = await findPort()
app = await blitzLaunchApp(appPort, {cwd: process.cwd()})
} catch (error) {

View File

@@ -16,19 +16,19 @@
"schema": "db/schema.prisma"
},
"dependencies": {
"@blitzjs/auth": "2.0.0-beta.31",
"@blitzjs/next": "2.0.0-beta.31",
"@blitzjs/rpc": "2.0.0-beta.31",
"@blitzjs/auth": "2.0.0-beta.36",
"@blitzjs/next": "2.0.0-beta.36",
"@blitzjs/rpc": "2.0.0-beta.36",
"@prisma/client": "4.6.1",
"blitz": "2.0.0-beta.31",
"blitz": "2.0.0-beta.36",
"lowdb": "3.0.0",
"next": "13.3.0",
"next": "13.5.2",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"@blitzjs/config": "2.0.0-beta.31",
"@blitzjs/config": "2.0.0-beta.36",
"@next/bundle-analyzer": "12.0.8",
"@types/express": "4.17.13",
"@types/fs-extra": "9.0.13",

View File

@@ -15,7 +15,7 @@ import webdriver from "../../utils/next-webdriver"
import {join} from "path"
let app: any
let appPort: number = 3000
let appPort: number
const appDir = join(__dirname, "../")
const runTests = (mode?: string) => {
@@ -50,7 +50,7 @@ describe("getInitialProps Tests", () => {
describe("dev mode", () => {
beforeAll(async () => {
try {
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
appPort = await findPort()
app = await blitzLaunchApp(appPort, {cwd: process.cwd()})
} catch (error) {

View File

@@ -1,5 +1,6 @@
/// <reference types="next" />
/// <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.

View File

@@ -11,11 +11,11 @@
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next"
},
"dependencies": {
"@blitzjs/config": "2.0.0-beta.31",
"@blitzjs/next": "2.0.0-beta.31",
"@blitzjs/rpc": "2.0.0-beta.31",
"blitz": "2.0.0-beta.31",
"next": "13.3.0",
"@blitzjs/config": "2.0.0-beta.36",
"@blitzjs/next": "2.0.0-beta.36",
"@blitzjs/rpc": "2.0.0-beta.36",
"blitz": "2.0.0-beta.36",
"next": "13.5.2",
"react": "18.2.0",
"react-dom": "18.2.0"
},

View File

@@ -13,7 +13,7 @@ import {
import {join} from "path"
let app: any
let appPort: number = 3000
let appPort: number
const appDir = join(__dirname, "../")
const runTests = () => {

View File

@@ -1,10 +1,16 @@
{
"extends": "@blitzjs/config/tsconfig.nextjs.json",
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "types"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "types", ".next/types/**/*.ts"],
"compilerOptions": {
"paths": {
"react": ["./node_modules/@types/react"]
}
},
"plugins": [
{
"name": "next"
}
],
"strictNullChecks": true
},
"exclude": ["node_modules"],
"baseUrl": "."

View File

@@ -17,14 +17,14 @@
"prisma:studio": "prisma studio"
},
"dependencies": {
"@blitzjs/auth": "2.0.0-beta.31",
"@blitzjs/config": "2.0.0-beta.31",
"@blitzjs/next": "2.0.0-beta.31",
"@blitzjs/rpc": "2.0.0-beta.31",
"@blitzjs/auth": "2.0.0-beta.36",
"@blitzjs/config": "2.0.0-beta.36",
"@blitzjs/next": "2.0.0-beta.36",
"@blitzjs/rpc": "2.0.0-beta.36",
"@prisma/client": "4.6.1",
"blitz": "2.0.0-beta.31",
"blitz": "2.0.0-beta.36",
"lowdb": "3.0.0",
"next": "13.3.0",
"next": "13.5.2",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0",

View File

@@ -7,7 +7,7 @@ import fetch from "node-fetch"
import {fromBase64} from "b64-lite"
let app: any
let appPort: number = 3000
let appPort: number
const HEADER_CSRF = "anti-csrf"
const COOKIE_PUBLIC_DATA_TOKEN = "auth-tests-cookie-prefix_sPublicDataToken"
const COOKIE_SESSION_TOKEN = "auth-tests-cookie-prefix_sSessionToken"
@@ -156,7 +156,7 @@ describe("Auth Tests", () => {
describe("dev mode", async () => {
beforeAll(async () => {
try {
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
appPort = await findPort()
app = await blitzLaunchApp(appPort, {cwd: process.cwd()})
} catch (error) {

View File

@@ -16,19 +16,19 @@
"prisma:studio": "prisma studio"
},
"dependencies": {
"@blitzjs/auth": "2.0.0-beta.31",
"@blitzjs/next": "2.0.0-beta.31",
"@blitzjs/rpc": "2.0.0-beta.31",
"@blitzjs/auth": "2.0.0-beta.36",
"@blitzjs/next": "2.0.0-beta.36",
"@blitzjs/rpc": "2.0.0-beta.36",
"@prisma/client": "4.6.1",
"blitz": "2.0.0-beta.31",
"blitz": "2.0.0-beta.36",
"lowdb": "3.0.0",
"next": "13.3.0",
"next": "13.5.2",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"@blitzjs/config": "2.0.0-beta.31",
"@blitzjs/config": "2.0.0-beta.36",
"@next/bundle-analyzer": "12.0.8",
"@types/express": "4.17.13",
"@types/fs-extra": "9.0.13",

View File

@@ -15,7 +15,7 @@ import webdriver from "../../utils/next-webdriver"
import {join} from "path"
let app: any
let appPort: number = 3000
let appPort: number
const appDir = join(__dirname, "../")
const runTests = (mode?: string) => {
@@ -40,7 +40,7 @@ describe("No Suspense Tests", () => {
describe("dev mode", () => {
beforeAll(async () => {
try {
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
appPort = await findPort()
app = await blitzLaunchApp(appPort, {cwd: process.cwd()})
} catch (error) {

View File

@@ -8,14 +8,14 @@
"clean": "rm -rf .turbo && rm -rf node_modules"
},
"dependencies": {
"@blitzjs/auth": "2.0.0-beta.31",
"@blitzjs/config": "2.0.0-beta.31",
"@blitzjs/next": "2.0.0-beta.31",
"@blitzjs/rpc": "2.0.0-beta.31",
"@blitzjs/auth": "2.0.0-beta.36",
"@blitzjs/config": "2.0.0-beta.36",
"@blitzjs/next": "2.0.0-beta.36",
"@blitzjs/rpc": "2.0.0-beta.36",
"@prisma/client": "4.6.1",
"@tanstack/react-query": "4.0.10",
"blitz": "2.0.0-beta.31",
"next": "13.3.0",
"blitz": "2.0.0-beta.36",
"next": "13.5.2",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0"

View File

@@ -4,7 +4,7 @@ import {useQuery, useInfiniteQuery, BlitzRpcPlugin, QueryClientProvider} from "@
import React from "react"
import delay from "delay"
import {buildMutationRpc, buildQueryRpc, mockRouter, render} from "../../utils/blitz-test-utils"
import {RouterContext} from "next/dist/shared/lib/router-context"
import {RouterContext} from "@blitzjs/next"
beforeAll(() => {
globalThis.__BLITZ_SESSION_COOKIE_PREFIX = "qm-test-cookie-prefix"

View File

@@ -1,5 +1,6 @@
/// <reference types="next" />
/// <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.

View File

@@ -16,18 +16,18 @@
"schema": "db/schema.prisma"
},
"dependencies": {
"@blitzjs/next": "2.0.0-beta.31",
"@blitzjs/rpc": "2.0.0-beta.31",
"@blitzjs/next": "2.0.0-beta.36",
"@blitzjs/rpc": "2.0.0-beta.36",
"@prisma/client": "4.6.1",
"blitz": "2.0.0-beta.31",
"blitz": "2.0.0-beta.36",
"lowdb": "3.0.0",
"next": "13.3.0",
"next": "13.5.2",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"@blitzjs/config": "2.0.0-beta.31",
"@blitzjs/config": "2.0.0-beta.36",
"@next/bundle-analyzer": "12.0.8",
"@types/express": "4.17.13",
"@types/fs-extra": "9.0.13",

View File

@@ -10,7 +10,7 @@ import {
import webdriver from "../../utils/next-webdriver"
let app: any
let appPort: number = 3000
let appPort: number
const runTests = () => {
describe("get query data", () => {
@@ -114,7 +114,7 @@ describe("React Query Utils Tests", () => {
describe("dev mode", () => {
beforeAll(async () => {
try {
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
appPort = await findPort()
app = await blitzLaunchApp(appPort, {cwd: process.cwd()})
} catch (error) {

View File

@@ -1,10 +1,16 @@
{
"extends": "@blitzjs/config/tsconfig.nextjs.json",
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "types"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "types", ".next/types/**/*.ts"],
"compilerOptions": {
"paths": {
"react": ["./node_modules/@types/react"]
}
},
"plugins": [
{
"name": "next"
}
],
"strictNullChecks": true
},
"exclude": ["node_modules"],
"baseUrl": "."

View File

@@ -7,11 +7,11 @@
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next"
},
"dependencies": {
"@blitzjs/config": "2.0.0-beta.31",
"@blitzjs/next": "2.0.0-beta.31",
"@blitzjs/rpc": "2.0.0-beta.31",
"blitz": "2.0.0-beta.31",
"next": "13.3.0",
"@blitzjs/config": "2.0.0-beta.36",
"@blitzjs/next": "2.0.0-beta.36",
"@blitzjs/rpc": "2.0.0-beta.36",
"blitz": "2.0.0-beta.36",
"next": "13.5.2",
"react": "18.2.0",
"react-dom": "18.2.0"
},

View File

@@ -7,11 +7,11 @@
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next"
},
"dependencies": {
"@blitzjs/config": "2.0.0-beta.31",
"@blitzjs/next": "2.0.0-beta.31",
"@blitzjs/rpc": "2.0.0-beta.31",
"blitz": "2.0.0-beta.31",
"next": "13.3.0",
"@blitzjs/config": "2.0.0-beta.36",
"@blitzjs/next": "2.0.0-beta.36",
"@blitzjs/rpc": "2.0.0-beta.36",
"blitz": "2.0.0-beta.36",
"next": "13.5.2",
"react": "18.2.0",
"react-dom": "18.2.0"
},

View File

@@ -16,19 +16,19 @@
"schema": "db/schema.prisma"
},
"dependencies": {
"@blitzjs/auth": "2.0.0-beta.31",
"@blitzjs/next": "2.0.0-beta.31",
"@blitzjs/rpc": "2.0.0-beta.31",
"@blitzjs/auth": "2.0.0-beta.36",
"@blitzjs/next": "2.0.0-beta.36",
"@blitzjs/rpc": "2.0.0-beta.36",
"@prisma/client": "4.6.1",
"blitz": "2.0.0-beta.31",
"blitz": "2.0.0-beta.36",
"lowdb": "3.0.0",
"next": "13.3.0",
"next": "13.5.2",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"@blitzjs/config": "2.0.0-beta.31",
"@blitzjs/config": "2.0.0-beta.36",
"@next/bundle-analyzer": "12.0.8",
"@types/express": "4.17.13",
"@types/fs-extra": "9.0.13",

View File

@@ -15,7 +15,7 @@ import webdriver from "../../utils/next-webdriver"
import {join} from "path"
let app: any
let appPort: number = 3000
let appPort: number
const appDir = join(__dirname, "../")
const runTests = (mode?: string) => {
@@ -39,7 +39,7 @@ describe("Trailing Slash Tests", () => {
describe("dev mode", () => {
beforeAll(async () => {
try {
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
appPort = await findPort()
app = await blitzLaunchApp(appPort, {cwd: process.cwd()})
} catch (error) {

View File

@@ -3,7 +3,7 @@ import {vi} from "vitest"
import {QueryClient} from "@tanstack/react-query"
import {BlitzRpcPlugin, QueryClientProvider} from "@blitzjs/rpc"
import {NextRouter} from "next/router"
import {RouterContext} from "next/dist/shared/lib/router-context"
import {RouterContext} from "@blitzjs/next"
import {render as defaultRender} from "@testing-library/react"
export const mockRouter: NextRouter = {
@@ -27,6 +27,7 @@ export const mockRouter: NextRouter = {
emit: vi.fn(),
},
isFallback: false,
forward: vi.fn(),
}
type DefaultParams = Parameters<typeof defaultRender>
@@ -74,7 +75,10 @@ const BlitzWrapper = ({plugins, children}) => {
)
}
export function render(ui: RenderUI, {wrapper, router, ...options}: RenderOptions = {}) {
export function render(
ui: RenderUI,
{wrapper, router, ...options}: RenderOptions = {},
): ReturnType<typeof defaultRender> {
if (!wrapper) {
wrapper = ({children}) => {
return <BlitzWrapper plugins={[BlitzRpcPlugin({})]}>{children}</BlitzWrapper>

View File

@@ -242,8 +242,8 @@ export function runBlitzCommandDev(argv, stdOut, opts: RunNextCommandDevOptions
function handleStdout(data) {
const message = data.toString()
const bootupMarkers = {
dev: /compiled .*successfully/i,
start: /started server/i,
dev: /Ready/i,
start: /Ready/i,
}
if (
(opts.bootupMarker && opts.bootupMarker.test(message)) ||
@@ -417,9 +417,10 @@ export function runNextCommandDev(argv, stdOut, opts: RunNextCommandDevOptions =
function handleStdout(data) {
const message = data.toString()
console.log(message)
const bootupMarkers = {
dev: /compiled .*successfully/i,
start: /started server/i,
dev: /Next.js/i,
start: /Next.js/i,
}
if (
(opts.bootupMarker && opts.bootupMarker.test(message)) ||
@@ -436,7 +437,7 @@ export function runNextCommandDev(argv, stdOut, opts: RunNextCommandDevOptions =
}
if (opts.stdout !== false) {
process.stdout.write(message)
process.stdout.write(message)
}
}

View File

@@ -3,8 +3,9 @@
"version": "0.0.0",
"private": true,
"devDependencies": {
"@blitzjs/config": "workspace: *",
"@blitzjs/rpc": "workspace: *",
"@blitzjs/config": "workspace:2.0.0-beta.36",
"@blitzjs/next": "workspace:2.0.0-beta.36",
"@blitzjs/rpc": "workspace:2.0.0-beta.36",
"@tanstack/react-query": "4.13.0",
"@testing-library/react": "13.4.0",
"@types/express": "4.17.13",

View File

@@ -29,12 +29,12 @@
"husky": "8.0.2",
"jsdom": "^19.0.0",
"lint-staged": "13.0.3",
"next": "13.3.0",
"next": "13.5.2",
"only-allow": "1.1.0",
"prettier": "^2.7.1",
"prettier-plugin-prisma": "4.4.0",
"pretty-quick": "3.1.3",
"turbo": "1.10.7",
"turbo": "1.10.9",
"vitest": "0.25.3",
"wait-on": "6.0.1"
},
@@ -47,7 +47,7 @@
},
"pnpm": {
"patchedDependencies": {
"@auth/core@0.10.0": "patches/@auth__core@0.10.0.patch"
"next-auth@4.18.7": "patches/next-auth@4.18.7.patch"
}
}
}

View File

@@ -1 +0,0 @@
adapters

View File

@@ -1,5 +1,70 @@
# @blitzjs/auth
## 2.0.0-beta.36
### Patch Changes
- 09e0c68db: Automatically authorize role with usage of `redirectAuthenticatedTo` in `useAuthenticatedBlitzContext` utility
- Updated dependencies [09e0c68db]
- blitz@2.0.0-beta.36
## 2.0.0-beta.35
### Patch Changes
- cee2dec17: Fix bug that did not allow `Page.authenicate = {role: "" }` to correctly work
- b97366c42: Remove unintended dependency on next-auth by removing it from the core build of @blitzjs/auth
⚠️ Breaking Change for current users of `withNextAuthAdapter`
Update your import in `next.config.js` in the following way
```diff
-const { withNextAuthAdapter } = require("@blitzjs/auth")
+const { withNextAuthAdapter } = require("@blitzjs/auth/next-auth")
```
- 3bcbad1a9: - Introduce Blitz RPC's logging system to the `invoke` function which is the recommended way to call resolvers in nextjs `app` directory's react server components.
- This refactor also removes the re-introduced dependency between `blitz-auth` and `blitz-rpc`, allowing independent usage of `blitz-rpc`
- Updated dependencies [cee2dec17]
- Updated dependencies [aec1bb076]
- Updated dependencies [b97366c42]
- Updated dependencies [3bcbad1a9]
- blitz@2.0.0-beta.35
## 2.0.0-beta.34
### Patch Changes
- 3ddb57072: ⚠️ Breaking Change:
Next.js version 13.5 or above is now required to use `@blitzjs/next`
Fix `Error: Cannot find module 'next/dist/shared/lib/router/utils/resolve-href'` by updating the location of next.js internal function.
- Updated dependencies [30fd61316]
- Updated dependencies [3ddb57072]
- Updated dependencies [fe8c937d2]
- blitz@2.0.0-beta.34
## 2.0.0-beta.33
### Patch Changes
- Updated dependencies [19898a488]
- Updated dependencies [6811eab1a]
- Updated dependencies [022392c12]
- blitz@2.0.0-beta.33
## 2.0.0-beta.32
### Patch Changes
- 8b01175b4: Updated `useAuthenticatedBlitzContext` to now return `AuthenticatedCtx`
- Updated dependencies [82649f341]
- blitz@2.0.0-beta.32
## 2.0.0-beta.31
### Patch Changes

View File

@@ -5,11 +5,7 @@ const config: BuildConfig = {
"./src/index-browser",
"./src/index-server",
"./src/server/secure-password",
{
builder: "mkdist",
input: "./src/adapters/",
outDir: "./adapters",
},
"./src/server/adapters/next-auth",
],
externals: ["index-browser.cjs", "index-browser.mjs", "react"],
declaration: true,

1
packages/blitz-auth/next-auth.d.ts vendored Normal file
View File

@@ -0,0 +1 @@
export * from "./dist/next-auth"

View File

@@ -0,0 +1 @@
module.exports = require("./dist/next-auth.cjs")

View File

@@ -1,6 +1,6 @@
{
"name": "@blitzjs/auth",
"version": "2.0.0-beta.31",
"version": "2.0.0-beta.36",
"homepage": "https://blitzjs.com/",
"repository": {
"type": "git",
@@ -24,7 +24,7 @@
"files": [
"dist/**",
"secure-password.*",
"adapters/**"
"next-auth.*"
],
"dependencies": {
"@types/b64-lite": "1.3.0",
@@ -50,9 +50,9 @@
"url": "0.11.0"
},
"peerDependencies": {
"@auth/core": "*",
"blitz": "2.0.0-beta.31",
"blitz": "2.0.0-beta.36",
"next": "*",
"next-auth": "*",
"secure-password": "4.0.0"
},
"peerDependenciesMeta": {
@@ -62,13 +62,12 @@
"secure-password": {
"optional": true
},
"@auth/core": {
"next-auth": {
"optional": true
}
},
"devDependencies": {
"@auth/core": "0.10.0",
"@blitzjs/config": "2.0.0-beta.31",
"@blitzjs/config": "2.0.0-beta.36",
"@testing-library/react": "13.4.0",
"@testing-library/react-hooks": "8.0.1",
"@types/cookie": "0.4.1",
@@ -76,8 +75,9 @@
"@types/jsonwebtoken": "8.5.8",
"@types/react": "18.0.25",
"@types/react-dom": "17.0.14",
"blitz": "2.0.0-beta.31",
"next": "13.3.0",
"blitz": "2.0.0-beta.36",
"next": "13.5.2",
"next-auth": "4.18.7",
"react": "18.2.0",
"react-dom": "18.2.0",
"secure-password": "4.0.0",

View File

@@ -1 +0,0 @@
!adapters

View File

@@ -1,2 +0,0 @@
export * from "./authjs/adapter"
export * from "./authjs/types"

View File

@@ -1,3 +0,0 @@
# Auth Core Internals for Blitz
This directory contains the internals of the Auth Core being used by the blitz adapter.

View File

@@ -1,9 +0,0 @@
export function isLocalhost(req: any): boolean {
let {host} = req.headers
let localhost = false
if (host) {
host = host.split(":")[0]
localhost = host === "localhost"
}
return localhost
}

View File

@@ -310,12 +310,12 @@ function withBlitzAuthPlugin<TProps = any>(Page: ComponentType<TProps> | BlitzPa
}, [])
let {authenticate, redirectAuthenticatedTo} = getAuthValues(Page, props)
useAuthorizeIf(
authenticate === true,
!!authenticate &&
((typeof authenticate === "object" && authenticate.redirectTo === undefined) ||
authenticate === true),
!authenticate ? undefined : typeof authenticate === "object" ? authenticate.role : undefined,
)
if (typeof window !== "undefined") {
const publicData = getPublicDataStore().getData()

View File

@@ -1,8 +1,10 @@
import {AuthPluginOptions} from "./server"
import {SessionConfigMethods} from "./shared"
import type {Ctx} from "blitz"
import type {AuthPluginOptions} from "./server"
import type {SessionConfigMethods} from "./shared"
declare global {
var sessionConfig: AuthPluginOptions & SessionConfigMethods
var __BLITZ_SESSION_COOKIE_PREFIX: string | undefined
var __BLITZ_SUSPENSE_ENABLED: boolean
var __BLITZ_GET_RSC_CONTEXT: () => Promise<Ctx>
}

View File

@@ -1,4 +1,4 @@
import "./global"
export * from "./adapters"
export * from "./index-browser"
export * from "./server"

View File

@@ -0,0 +1,2 @@
export * from "./next-auth/adapter"
export * from "./next-auth/types"

View File

@@ -11,26 +11,27 @@ import {
secureProxyMiddleware,
truncateString,
} from "blitz"
import {isLocalhost, SessionContext} from "../../../index-server"
export {withNextAuthAdapter} from "./webpack"
// next-auth internals
import {toInternalRequest, toResponse} from "./internals/utils/web"
import {getBody, getURL, setHeaders} from "./internals/utils/node"
import type {RequestInternal, AuthOptions, User} from "next-auth"
import type {Cookie} from "next-auth/core/lib/cookie"
import type {AuthAction, InternalOptions} from "./internals/core/types"
import type {
ApiHandlerIncomingMessage,
BlitzNextAuthApiHandler,
BlitzNextAuthOptions,
} from "./types"
import {isLocalhost} from "../utils"
import {Provider} from "next-auth/providers"
// next-auth internals
import {getBody, getURL, setHeaders} from "./internals/core/node"
import type {AuthAction, InternalOptions, RequestInternal} from "./internals/core/types"
import type {OAuthConfig} from "@auth/core/providers"
import type {Cookie} from "@auth/core/lib/cookie"
import {init} from "@auth/core/lib/init"
import emailSignIn from "@auth/core/lib/email/signin"
import {getAuthorizationUrl} from "@auth/core/lib/oauth/authorization-url"
import {handleOAuth} from "@auth/core/lib/oauth/callback"
import {handleState} from "@auth/core/lib/oauth/handle-state"
import {toInternalRequest, toResponse} from "@auth/core/lib/web"
import {assertConfig} from "@auth/core/lib/assert"
import {init} from "next-auth/core/init"
import getAuthorizationUrl from "next-auth/core/lib/oauth/authorization-url"
import oAuthCallback from "next-auth/core/lib/oauth/callback"
const INTERNAL_REDIRECT_URL_KEY = "_redirectUrl"
@@ -43,38 +44,41 @@ function switchURL(callbackUrl: string) {
return `${url.protocol}//${url.host}${switchPathNameString}${url.search}${url.hash}`
}
export function AuthAdapter<P extends OAuthConfig<any>[]>(
export function NextAuthAdapter<P extends Provider[]>(
config: BlitzNextAuthOptions<P>,
): BlitzNextAuthApiHandler {
return async function authHandler(req, res) {
assert(
req.query.nextauth,
"req.query.nextauth is not defined. Page must be named [...nextauth].ts/js.",
"req.query.nextauth is not defined. Page must be named [...auth].ts/js.",
)
assert(
Array.isArray(req.query.nextauth),
"req.query.nextauth must be an array. Page must be named [...nextauth].ts/js.",
"req.query.nextauth must be an array. Page must be named [...auth].ts/js.",
)
if (!req.query.nextauth?.length) {
return res.status(404).end()
}
const action = req.query.nextauth[1] as AuthAction
if (!action || !["signin", "callback"].includes(action)) {
if (!action || !["login", "callback"].includes(action)) {
return res.status(404).end()
}
const cookieSessionMiddleware = cookieSession({
secret: process.env.SESSION_SECRET_KEY || "default-dev-secret",
secure: process.env.NODE_ENV === "production" && !isLocalhost(req),
})
const middleware: RequestMiddleware<ApiHandlerIncomingMessage, MiddlewareResponse<Ctx>>[] = [
connectMiddleware(cookieSessionMiddleware as RequestMiddleware),
]
if (config.secureProxy) {
middleware.push(secureProxyMiddleware)
}
const headers = new Headers(req.headers as any)
const url = getURL(req.url, headers)
log.debug("NEXT_AUTH_URL", url)
if (url instanceof Error) {
if (process.env.NODE_ENV !== "production") throw url
const errorLogger = config.logger?.error ?? console.error
@@ -90,46 +94,37 @@ export function AuthAdapter<P extends OAuthConfig<any>[]>(
method: req.method,
...getBody(req),
})
log.debug("NEXT_AUTH_REQUEST")
const internalRequest = await toInternalRequest(request)
log.debug("NEXT_AUTH_INTERNAL_REQUEST", internalRequest)
if (internalRequest instanceof Error) {
console.error((request as any).code, request)
return res.status(500).json({
message:
"There was a problem with the server configuration. Check the server logs for more information.",
return new Response(`Error: This action with HTTP ${request.method} is not supported.`, {
status: 400,
})
}
const assertionResult = assertConfig(internalRequest, config)
if (Array.isArray(assertionResult)) {
assertionResult.forEach(log.error)
} else if (assertionResult instanceof Error) {
// Bail out early if there's an error in the user config
log.error(assertionResult.message)
return res.status(500).json({
message:
"There was a problem with the server configuration. Check the server logs for more information.",
code: assertionResult.name,
})
let {providerId} = internalRequest
if (providerId?.includes("?")) {
providerId = providerId.split("?")[0]
}
const callbackUrl = req.body?.callbackUrl ?? req.query?.callbackUrl?.toString()
const {options, cookies} = await init({
// @ts-ignore
url: new URL(
internalRequest.url,
// @ts-ignore
internalRequest.url!,
process.env.APP_ORIGIN || process.env.BLITZ_DEV_SERVER_ORIGIN,
),
authOptions: config,
authOptions: config as unknown as AuthOptions,
action,
providerId: internalRequest.providerId.includes("?")
? internalRequest.providerId.split("?")[0]
: internalRequest.providerId,
callbackUrl,
providerId,
callbackUrl: req.body?.callbackUrl ?? (req.query?.callbackUrl as string),
cookies: internalRequest.cookies,
isPost: req.method === "POST",
csrfDisabled: config.csrf?.enabled ?? false,
})
options.provider.callbackUrl = switchURL(options.provider.callbackUrl)
log.debug("NEXT_AUTH_INTERNAL_OPTIONS", options)
await AuthHandler(middleware, config, internalRequest, action, options, cookies)
.then(async ({middleware}) => {
await handleRequestWithMiddleware<ApiHandlerIncomingMessage, MiddlewareResponse<Ctx>>(
@@ -152,14 +147,7 @@ export function AuthAdapter<P extends OAuthConfig<any>[]>(
}
}
function defaultNormalizer(email?: string) {
if (!email) throw new Error("Missing email from request body.")
let [local, domain] = email.toLowerCase().trim().split("@")
domain = domain?.split(",")[0]
return `${local}@${domain}`
}
export async function AuthHandler<P extends OAuthConfig<any>[]>(
async function AuthHandler<P extends Provider[]>(
middleware: RequestMiddleware<ApiHandlerIncomingMessage, MiddlewareResponse<Ctx>>[],
config: BlitzNextAuthOptions<P>,
internalRequest: RequestInternal,
@@ -170,34 +158,23 @@ export async function AuthHandler<P extends OAuthConfig<any>[]>(
if (!options.provider) {
throw new OAuthError("MISSING_PROVIDER_ERROR")
}
if (action === "signin") {
middleware.push(async (req, res, _next) => {
if (action === "login") {
middleware.push(async (req, res, next) => {
try {
if (options.provider.type === "oauth" || options.provider.type === "oidc") {
const _signin = await getAuthorizationUrl(req.query, options)
log.debug("NEXT_AUTH_SIGNIN", _signin)
if (_signin.cookies) cookies.push(..._signin.cookies)
await res.blitzCtx.session.$setPublicData({
[INTERNAL_REDIRECT_URL_KEY]: _signin.redirect,
} as any)
const response = toResponse(_signin)
setHeaders(response.headers, res)
log.debug("NEXT_AUTH_SIGNIN_REDIRECT", _signin.redirect)
res.setHeader("Location", _signin.redirect)
res.statusCode = 302
res.end()
} else if (options.provider.type === "email") {
const normalizer = options.provider.normalizeIdentifier ?? defaultNormalizer
const email = normalizer(internalRequest.body?.email)
const redirect = await emailSignIn(email, options, internalRequest)
res.setHeader("Location", redirect)
res.statusCode = 302
res.end()
} else {
throw new OAuthError("UNSUPPORTED_PROVIDER_ERROR")
}
const _signin = await getAuthorizationUrl({options: options, query: req.query})
if (_signin.cookies) cookies.push(..._signin.cookies)
const session = res.blitzCtx.session as SessionContext
assert(session, "Missing Blitz sessionMiddleware!")
await session.$setPublicData({
[INTERNAL_REDIRECT_URL_KEY]: _signin.redirect,
} as any)
const response = toResponse(_signin)
setHeaders(response.headers, res)
res.setHeader("Location", _signin.redirect)
res.statusCode = 302
res.end()
} catch (e) {
log.error("OAUTH_SIGNIN_Error in AuthAdapter " + (e as Error).toString())
log.error("OAUTH_SIGNIN_Error in NextAuthAdapter " + (e as Error).toString())
console.log(e)
const authErrorQueryStringKey = config.errorRedirectUrl.includes("?")
? "&authError="
@@ -212,27 +189,19 @@ export async function AuthHandler<P extends OAuthConfig<any>[]>(
return {middleware}
} else if (action === "callback") {
middleware.push(
connectMiddleware(async (req, res, _next) => {
// eslint-disable-next-line no-shadow
connectMiddleware(async (req, res, next) => {
try {
const {proxyRedirect, randomState} = handleState(
req.query,
options.provider,
options.isOnRedirectProxy,
)
if (proxyRedirect) {
log.debug("proxy redirect", {proxyRedirect, randomState})
res.setHeader("Location", proxyRedirect)
res.statusCode = 302
res.end()
}
const {cookies, profile, account, user} = await handleOAuth(
req.query,
internalRequest.cookies,
options,
)
log.debug("NEXT_AUTH_CALLBACK", {cookies, profile, account, user})
const session = res.blitzCtx.session
const callback = await config.callback(user, account, profile as any, session)
const {profile, account, OAuthProfile} = await oAuthCallback({
query: internalRequest.query,
body: internalRequest.body || {code: req.query.code, state: req.query.state},
method: "POST",
options: options as any,
cookies: internalRequest.cookies,
})
const session = res.blitzCtx.session as SessionContext
assert(session, "Missing Blitz sessionMiddleware!")
const callback = await config.callback(profile as User, account, OAuthProfile!, session)
let _redirect = config.successRedirectUrl
if (callback instanceof Object) {
_redirect = callback.redirectUrl
@@ -241,12 +210,13 @@ export async function AuthHandler<P extends OAuthConfig<any>[]>(
redirect: _redirect,
cookies: cookies,
})
setHeaders(response.headers, res)
res.setHeader("Location", _redirect)
res.statusCode = 302
res.end()
} catch (e) {
log.error("OAUTH_CALLBACK_Error in AuthAdapter " + (e as Error).toString())
log.error("OAUTH_CALLBACK_Error in NextAuthAdapter " + (e as Error).toString())
console.log(e)
const authErrorQueryStringKey = config.errorRedirectUrl.includes("?")
? "&authError="

View File

@@ -0,0 +1,3 @@
# Next-auth Internals
This directory contains the internals of the Next-auth being used by the blitz adapter.

View File

@@ -1,7 +1,6 @@
import type {AuthConfig} from "@auth/core"
import {EventCallbacks, PagesOptions, CookiesOptions, CallbacksOptions} from "@auth/core/types"
import type {Adapter} from "@auth/core/adapters"
import type {JWTOptions} from "@auth/core/jwt"
import type {CallbacksOptions, CookiesOptions, EventCallbacks} from "next-auth"
import type {Adapter} from "next-auth/adapters"
import type {JWTOptions} from "next-auth/jwt"
import type {
OAuthConfig,
ProviderType,
@@ -10,7 +9,7 @@ import type {
AuthorizationEndpointHandler,
EmailConfig,
CredentialsConfig,
} from "@auth/core/providers"
} from "next-auth/providers"
export interface OAuthConfigInternal<P>
extends Omit<OAuthConfig<P>, "authorization" | "token" | "userinfo"> {
@@ -34,7 +33,7 @@ export type AuthAction =
| "providers"
| "session"
| "csrf"
| "signin"
| "login"
| "signout"
| "callback"
| "verify-request"
@@ -62,40 +61,26 @@ export interface LoggerInstance extends Record<string, Function> {
debug: (code: string, metadata: unknown) => void
}
export interface RequestInternal {
url: URL
method: "GET" | "POST"
cookies?: Partial<Record<string, string>>
headers?: Record<string, any>
query?: Record<string, any>
body?: Record<string, any>
action: AuthAction
providerId?: string
error?: string
}
export interface InternalOptions<TProviderType = ProviderType> {
export interface InternalOptions<
TProviderType = ProviderType,
WithVerificationToken = TProviderType extends "email" ? true : false,
> {
providers: InternalProvider[]
url: URL
action: AuthAction
provider: InternalProvider<TProviderType>
csrfToken?: string
csrfTokenVerified?: boolean
secret: string
theme: Theme
debug: boolean
logger: LoggerInstance
session: NonNullable<Required<AuthConfig["session"]>>
pages: Partial<PagesOptions>
session: Required<LoggerInstance>
pages: any
jwt: JWTOptions
events: Partial<EventCallbacks>
adapter: Required<Adapter> | undefined
adapter: WithVerificationToken extends true
? Adapter<WithVerificationToken>
: Adapter<WithVerificationToken> | undefined
callbacks: CallbacksOptions
cookies: CookiesOptions
callbackUrl: string
/**
* If true, the OAuth callback is being proxied by the server to the original URL.
* See also {@link OAuthConfigInternal.redirectProxyUrl}.
*/
isOnRedirectProxy: boolean
}

View File

@@ -0,0 +1,39 @@
export interface InternalUrl {
/** @default "http://localhost:3000" */
origin: string
/** @default "localhost:3000" */
host: string
/** @default "/api/auth" */
path: string
/** @default "http://localhost:3000/api/auth" */
base: string
/** @default "http://localhost:3000/api/auth" */
toString: () => string
}
/**
* TODO: Can we remove this?
* Returns an `URL` like object to make requests/redirects from server-side
*/
export default function parseUrl(url?: string | URL): InternalUrl {
const defaultUrl = new URL("http://localhost:3000/api/auth")
if (url && !url.toString().startsWith("http")) {
url = `https://${url}`
}
const _url = new URL(url ?? defaultUrl)
const path = (_url.pathname === "/" ? defaultUrl.pathname : _url.pathname)
// Remove trailing slash
.replace(/\/$/, "")
const base = `${_url.origin}${path}`
return {
origin: _url.origin,
host: _url.host,
path,
base,
toString: () => base,
}
}

View File

@@ -0,0 +1,115 @@
import {OAuthError} from "blitz"
import {serialize, parse as parseCookie} from "cookie"
import type {ResponseInternal, RequestInternal} from "next-auth/core"
import type {AuthAction} from "next-auth/core/types"
const decoder = new TextDecoder()
async function streamToString(stream: any): Promise<string> {
const chunks: Uint8Array[] = []
return await new Promise((resolve, reject) => {
stream.on("data", (chunk: WithImplicitCoercion<ArrayBuffer | SharedArrayBuffer>) =>
chunks.push(Buffer.from(chunk)),
)
stream.on("error", (err: any) => reject(err))
stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")))
})
}
async function readJSONBody(
body: ReadableStream | Buffer,
): Promise<Record<string, any> | undefined> {
try {
if ("getReader" in body) {
const reader = body.getReader()
const bytes: number[] = []
while (true) {
const {value, done} = await reader.read()
if (done) break
bytes.push(...value)
}
const b = new Uint8Array(bytes)
return JSON.parse(decoder.decode(b))
}
// node-fetch
if (typeof Buffer !== "undefined" && Buffer.isBuffer(body)) {
return JSON.parse(body.toString("utf8"))
}
return JSON.parse(await streamToString(body))
} catch (e) {
console.error(e)
}
}
// prettier-ignore
const actions = [ "providers", "session", "csrf", "login", "signout", "callback", "verify-request", "error", "_log"]
export async function toInternalRequest(req: Request): Promise<RequestInternal | Error> {
try {
// TODO: url.toString() should not include action and providerId
// see init.ts
const url = new URL(req.url.replace(/\/$/, ""))
const {pathname} = url
const action = actions.find((a) => pathname.includes(a)) as AuthAction | undefined
if (!action) {
throw new OAuthError("Cannot detect action.")
}
const providerIdOrAction = pathname.split("/").pop()
let providerId
if (
providerIdOrAction &&
!action.includes(providerIdOrAction) &&
["login", "callback"].includes(action)
) {
providerId = providerIdOrAction
}
return {
//@ts-ignore
url,
action,
providerId,
method: req.method ?? "GET",
headers: Object.fromEntries(req.headers),
body: req.body ? await readJSONBody(req.body) : undefined,
cookies: parseCookie(req.headers.get("cookie") ?? "") ?? {},
error: url.searchParams.get("error") ?? undefined,
query: Object.fromEntries(url.searchParams),
}
} catch (error) {
return error as Error
}
}
export function toResponse(res: ResponseInternal): Response {
const headers = new Headers(res.headers as unknown as HeadersInit)
res.cookies?.forEach((cookie) => {
const {name, value, options} = cookie
const cookieHeader = serialize(name, value, options)
if (headers.has("Set-Cookie")) {
headers.append("Set-Cookie", cookieHeader)
} else {
headers.set("Set-Cookie", cookieHeader)
}
})
const body =
headers.get("content-type") === "application/json" ? JSON.stringify(res.body) : res.body
const response = new Response(body, {
headers,
status: res.redirect ? 302 : res.status ?? 200,
})
if (res.redirect) {
response.headers.set("Location", res.redirect)
}
return response
}

View File

@@ -1,22 +1,19 @@
import type {Ctx, MiddlewareResponse} from "blitz"
import type {IncomingMessage} from "http"
import type {Account, Profile, User} from "@auth/core/types"
import type {AuthConfig} from "@auth/core"
import type {SessionContext} from "../../index-server"
import type {OAuthConfig} from "@auth/core/providers"
import type {AuthOptions, Profile, User} from "next-auth"
import {SessionContext} from "../../../index-server"
import oAuthCallback from "next-auth/core/lib/oauth/callback"
import {OAuthConfig, Provider} from "next-auth/providers"
export type BlitzNextAuthOptions<P extends OAuthConfig<any>[]> = Omit<AuthConfig, "providers"> & {
export type BlitzNextAuthOptions<P extends Provider[]> = Omit<AuthOptions, "providers"> & {
providers: P
successRedirectUrl: string
errorRedirectUrl: string
secureProxy?: boolean
csrf?: {
enabled: boolean
}
callback: (
user: User | undefined,
account: Account | undefined,
profile: P[number] extends OAuthConfig<infer T> ? T : Profile,
user: User,
account: Awaited<ReturnType<typeof oAuthCallback>>["account"],
profile: P[0] extends OAuthConfig<any> ? Parameters<P[0]["profile"]>[0] : Profile,
session: SessionContext,
) => Promise<void | {redirectUrl: string}>
}

View File

@@ -0,0 +1,30 @@
//@ts-nocheck
import path from "path"
export function withNextAuthAdapter(nextConfig) {
const config = Object.assign({}, nextConfig)
try {
const nextAuthPath = path.dirname(require.resolve("next-auth"))
const webpack = (config) => {
config.resolve.alias = {
...config.resolve.alias,
"next-auth/core/lib/oauth/callback": path.join(nextAuthPath, "core/lib/oauth/callback.js"),
"next-auth/core/lib/oauth/authorization-url": path.join(
nextAuthPath,
"core/lib/oauth/authorization-url.js",
),
"next-auth/core/init": path.join(nextAuthPath, "core/init.js"),
}
return config
}
if (typeof nextConfig.webpack === "function") {
config.webpack = (config, options) => {
return nextConfig.webpack(webpack(config), options)
}
}
config.webpack = webpack
return config
} catch (e) {
return config
}
}

View File

@@ -1,7 +1,7 @@
/* @eslint-disable no-redeclare */
import cookieSession from "cookie-session"
import passport from "passport"
import {isLocalhost} from "../utils"
import {isLocalhost} from "../../index"
import {
assert,
connectMiddleware,
@@ -12,7 +12,7 @@ import {
secureProxyMiddleware,
truncateString,
} from "blitz"
import type {SessionContext} from "../../shared"
import {SessionContext} from "../../../shared"
import {
BlitzPassportConfig,
ApiHandler,

View File

@@ -1,6 +1,6 @@
import type {AuthenticateOptions, Strategy} from "passport"
import type {IncomingMessage, ServerResponse} from "http"
import type {PublicData} from "../../shared"
import type {PublicData} from "../../../shared"
import type {Ctx, MiddlewareResponse} from "blitz"
export interface BlitzPassportConfigCallbackParams {

View File

@@ -1,4 +1,4 @@
import {BlitzServerPlugin, RequestMiddleware, Ctx, createServerPlugin} from "blitz"
import {RequestMiddleware, Ctx, createServerPlugin} from "blitz"
import {assert} from "blitz"
import {IncomingMessage, ServerResponse} from "http"
import {PublicData, SessionModel, SessionConfigMethods} from "../shared/types"
@@ -125,6 +125,9 @@ export const AuthServerPlugin = createServerPlugin((options: AuthPluginOptions)
}
return blitzSessionMiddleware
}
if (!globalThis.__BLITZ_GET_RSC_CONTEXT) {
globalThis.__BLITZ_GET_RSC_CONTEXT = getBlitzContext
}
return {
requestMiddlewares: [authPluginSessionMiddleware()],
exports: () => ({

View File

@@ -190,7 +190,7 @@ export async function getBlitzContext(): Promise<Ctx> {
const req = new IncomingMessage(new Socket()) as IncomingMessage & {
cookies: {[key: string]: string}
}
req.headers = Object.fromEntries(headers() as any)
req.headers = Object.fromEntries(headers())
const csrfToken = cookies().get(COOKIE_CSRF_TOKEN())
if (csrfToken) {
req.headers[HEADER_CSRF] = csrfToken.value
@@ -243,8 +243,17 @@ export async function useAuthenticatedBlitzContext({
? redirectAuthenticatedTo
: formatWithValidation(redirectAuthenticatedTo)
debug("[useAuthenticatedBlitzContext] Redirecting to", redirectUrl)
log.info("Authentication Redirect: " + customChalk.dim("(Authenticated)"), redirectUrl)
redirect(redirectUrl)
if (role) {
try {
ctx.session.$authorize(role)
} catch (e) {
log.info("Authentication Redirect: " + customChalk.dim(`Role ${role}`), redirectTo)
redirect(redirectUrl)
}
} else {
log.info("Authentication Redirect: " + customChalk.dim("(Authenticated)"), redirectUrl)
redirect(redirectUrl)
}
}
if (redirectTo && role) {
debug("[useAuthenticatedBlitzContext] redirectTo and role are both defined.")

View File

@@ -1,5 +1,7 @@
export * from "./auth-utils"
export * from "./auth-plugin"
export * from "./adapters"
export {
SessionContextClass,
getAllSessionHandlesForUser,

Some files were not shown because too many files have changed in this diff Show More