Compare commits
26 Commits
siddharth/
...
@blitzjs/n
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99541848b3 | ||
|
|
09e0c68db9 | ||
|
|
fb232d126e | ||
|
|
b97366c427 | ||
|
|
11eeebee67 | ||
|
|
c89cb943bb | ||
|
|
3bcbad1a91 | ||
|
|
98d04ed613 | ||
|
|
cee2dec179 | ||
|
|
aec1bb076b | ||
|
|
2c72af7175 | ||
|
|
465a5c0720 | ||
|
|
353af3fae6 | ||
|
|
3ddb57072b | ||
|
|
8477d44aa7 | ||
|
|
6802c67809 | ||
|
|
fe8c937d24 | ||
|
|
30fd613164 | ||
|
|
9a5ce2e8ea | ||
|
|
81290b478c | ||
|
|
19898a4886 | ||
|
|
6811eab1aa | ||
|
|
022392c123 | ||
|
|
e3522d65ef | ||
|
|
cb1600a821 | ||
|
|
e1bffdf3d6 |
@@ -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,
|
||||
|
||||
6
.changeset/afraid-ligers-build.md
Normal file
6
.changeset/afraid-ligers-build.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@blitzjs/auth": patch
|
||||
"blitz": patch
|
||||
---
|
||||
|
||||
Fix bug that did not allow `Page.authenicate = {role: "" }` to correctly work
|
||||
6
.changeset/chatty-scissors-jump.md
Normal file
6
.changeset/chatty-scissors-jump.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@blitzjs/next": patch
|
||||
"blitz": patch
|
||||
---
|
||||
|
||||
blitz-next: Fix `next/head` used in app directory warning
|
||||
5
.changeset/green-years-behave.md
Normal file
5
.changeset/green-years-behave.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@blitzjs/generator": patch
|
||||
---
|
||||
|
||||
Upgrade next, prisma and zod to latest versions in a newly created app
|
||||
6
.changeset/hot-knives-vanish.md
Normal file
6
.changeset/hot-knives-vanish.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@blitzjs/auth": patch
|
||||
"blitz": patch
|
||||
---
|
||||
|
||||
Automatically authorize role with usage of `redirectAuthenticatedTo` in `useAuthenticatedBlitzContext` utility
|
||||
6
.changeset/little-cycles-hang.md
Normal file
6
.changeset/little-cycles-hang.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"blitz": patch
|
||||
---
|
||||
|
||||
- Removes language selection step from `blitz new` menu
|
||||
- Make `formik` the default/recommended form library
|
||||
10
.changeset/lucky-teachers-sleep.md
Normal file
10
.changeset/lucky-teachers-sleep.md
Normal 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.
|
||||
13
.changeset/modern-insects-raise.md
Normal file
13
.changeset/modern-insects-raise.md
Normal 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")
|
||||
9
.changeset/moody-pandas-do.md
Normal file
9
.changeset/moody-pandas-do.md
Normal 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`
|
||||
5
.changeset/neat-gorillas-switch.md
Normal file
5
.changeset/neat-gorillas-switch.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@blitzjs/recipe-tailwind": patch
|
||||
---
|
||||
|
||||
Change tailwind recipe to install dependencies as devDependencies
|
||||
6
.changeset/nervous-shrimps-serve.md
Normal file
6
.changeset/nervous-shrimps-serve.md
Normal 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.
|
||||
6
.changeset/nice-cats-lay.md
Normal file
6
.changeset/nice-cats-lay.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@blitzjs/rpc": patch
|
||||
"blitz": patch
|
||||
---
|
||||
|
||||
Allow `.tsx` & `.jsx` file extensions to be used for resolvers
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
"@blitzjs/auth": major
|
||||
"blitz": patch
|
||||
---
|
||||
|
||||
Migrate `next-auth` adapter to use `@auth/core`
|
||||
@@ -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",
|
||||
|
||||
5
.changeset/pretty-snakes-search.md
Normal file
5
.changeset/pretty-snakes-search.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@blitzjs/recipe-next-ui": patch
|
||||
---
|
||||
|
||||
Add `framer-motion` as a dependency of `next-ui`
|
||||
5
.changeset/quick-crews-occur.md
Normal file
5
.changeset/quick-crews-occur.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"blitz": patch
|
||||
---
|
||||
|
||||
Remove rouge `console.log` during start
|
||||
9
.changeset/shaggy-boxes-exercise.md
Normal file
9
.changeset/shaggy-boxes-exercise.md
Normal 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
|
||||
17
.github/workflows/main.yml
vendored
17
.github/workflows/main.yml
vendored
@@ -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
|
||||
|
||||
11
README.md
11
README.md
@@ -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>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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={{
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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({}),
|
||||
})
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
})
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
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 |
@@ -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",
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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"])
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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) {
|
||||
|
||||
1
integration-tests/middleware/next-env.d.ts
vendored
1
integration-tests/middleware/next-env.d.ts
vendored
@@ -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.
|
||||
|
||||
@@ -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"
|
||||
},
|
||||
|
||||
@@ -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 = () => {
|
||||
|
||||
@@ -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": "."
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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": "."
|
||||
|
||||
@@ -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"
|
||||
},
|
||||
|
||||
@@ -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"
|
||||
},
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1
packages/blitz-auth/.gitignore
vendored
1
packages/blitz-auth/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
adapters
|
||||
@@ -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
|
||||
|
||||
@@ -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
1
packages/blitz-auth/next-auth.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export * from "./dist/next-auth"
|
||||
1
packages/blitz-auth/next-auth.js
Normal file
1
packages/blitz-auth/next-auth.js
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require("./dist/next-auth.cjs")
|
||||
@@ -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",
|
||||
|
||||
1
packages/blitz-auth/src/.gitignore
vendored
1
packages/blitz-auth/src/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
!adapters
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from "./authjs/adapter"
|
||||
export * from "./authjs/types"
|
||||
@@ -1,3 +0,0 @@
|
||||
# Auth Core Internals for Blitz
|
||||
|
||||
This directory contains the internals of the Auth Core being used by the blitz adapter.
|
||||
@@ -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
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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>
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import "./global"
|
||||
export * from "./adapters"
|
||||
|
||||
export * from "./index-browser"
|
||||
export * from "./server"
|
||||
|
||||
2
packages/blitz-auth/src/server/adapters/next-auth.ts
Normal file
2
packages/blitz-auth/src/server/adapters/next-auth.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./next-auth/adapter"
|
||||
export * from "./next-auth/types"
|
||||
@@ -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="
|
||||
@@ -0,0 +1,3 @@
|
||||
# Next-auth Internals
|
||||
|
||||
This directory contains the internals of the Next-auth being used by the blitz adapter.
|
||||
@@ -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
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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}>
|
||||
}
|
||||
30
packages/blitz-auth/src/server/adapters/next-auth/webpack.ts
Normal file
30
packages/blitz-auth/src/server/adapters/next-auth/webpack.ts
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
@@ -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 {
|
||||
@@ -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: () => ({
|
||||
|
||||
@@ -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.")
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user