blitz-js / legacy-framework

MIT License
3 stars 2 forks source link

Missing Blitz sessionMiddleware when trying to use passport-twitch-strategy #394

Closed Kiodok closed 2 years ago

Kiodok commented 2 years ago

What is the problem?

I'd like to include twitch login for my blitz application. I created a Button in the login form with a router.push to the route "/api/auth/twitch". After that I was able to login through twitch and authorize my app. I already tried the passport-twitch package, but found out that it is a bit outdated, last update years ago. So I switched to passport-twitch-strategy, which is just a few months old.

Now I'm stuck at the error shown below. Thank you in advance for your assistance.

Paste all your error logs here:

11:46:05.239 INFO Starting authentication via twitch... 
Starting authentication via twitch...
11:46:06.040 INFO Processing callback for twitch... 
Processing callback for twitch...
API resolved without sending a response for /api/auth/twitch/callback?code=8cq6pfk4wn26dmjjlt9vvogz75jeol&scope=, this may result in stalled requests.
(node:8084) UnhandledPromiseRejectionWarning: Error: Missing Blitz sessionMiddleware!
    at assert (F:\Blitz Projects\streamconnect\node_modules\next\dist\stdlib-server\passport-adapter.js:77:27)
    at F:\Blitz Projects\streamconnect\node_modules\next\dist\stdlib-server\passport-adapter.js:142:21
    at F:\Blitz Projects\streamconnect\node_modules\next\dist\stdlib-server\middleware.js:109:9
    at new Promise (<anonymous>)
    at withCallbackHandler (F:\Blitz Projects\streamconnect\node_modules\next\dist\stdlib-server\middleware.js:106:12)
    at connectHandler (F:\Blitz Projects\streamconnect\node_modules\next\dist\stdlib-server\middleware.js:118:16)
    at dispatch (F:\Blitz Projects\streamconnect\node_modules\next\dist\server\middleware.js:90:40)
    at secureProxyMiddleware (F:\Blitz Projects\streamconnect\node_modules\next\dist\stdlib-server\middleware.js:123:5)
    at dispatch (F:\Blitz Projects\streamconnect\node_modules\next\dist\server\middleware.js:90:40)
    at F:\Blitz Projects\streamconnect\node_modules\next\dist\stdlib-server\middleware.js:111:26
(node:8084) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not 
handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 4)

Paste all relevant code snippets here:

// app\api\auth\[...auth].ts:

import { passportAuth } from "blitz"
import { Strategy as TwitchStrategy } from "passport-twitch-strategy"
import db from "db"

export default passportAuth(({ ctx, req, res }) => ({
  successRedirectUrl: "/",
  errorRedirectUrl: "/",
  secureProxy: true,
  strategies: [
    {
      strategy: new TwitchStrategy({
        clientID: process.env.NEXT_PUBLIC_TWITCH_CLIENT_ID as string,
        clientSecret: process.env.NEXT_PUBLIC_TWITCH_CLIENT_SECRET as string,
        callbackURL:
          process.env.NEXT_PUBLIC_MODE === "production"
            ? "https://stream-connect.net/api/auth/twitch/callback"
            : "http://localhost:3000/api/auth/twitch/callback",
        scope: "user:read:email"
      },
      async function (_token, _tokenSecret, profile, done) {
        const publicData = {
          profile: profile
        }
        console.log(publicData)
        done(undefined, { publicData })
      }
      ),
    },
  ],
}))

What are detailed steps to reproduce this?

  1. Implemented a Button to your JSX-Code
  2. Add a variable const router = useRouter()
  3. onClick call a function with router.push("/api/auth/twitch")
  4. Add the file [...auth].ts to app\api\auth
  5. Copy paste my Code
  6. Run blitz dev
  7. Click on the button

Run blitz -v and paste the output here:

Windows 10 | win32-x64 | Node: v14.18.1

blitz: 0.40.0 (global)
blitz: 0.42.4 (local)

  Package manager: npm
  System:
    OS: Windows 10 10.0.19043
    CPU: (8) x64 Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
    Memory: 21.45 GB / 31.95 GB
  Binaries:
    Node: 14.18.1 - F:\Programme\NodeJS\node.EXE
    Yarn: 1.22.11 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 8.1.2 - F:\Programme\NodeJS\npm.CMD
    Watchman: Not Found
  npmPackages:
    @prisma/client: 3.1.1 => 3.1.1
    blitz: 0.42.4 => 0.42.4
    prisma: 2.27.0 => 2.27.0
    react: 18.0.0-alpha-9b76d2d7b-20210719 => 18.0.0-alpha-9b76d2d7b-20210719
    react-dom: 18.0.0-alpha-9b76d2d7b-20210719 => 18.0.0-alpha-9b76d2d7b-20210719
    typescript: ~4.3 => 4.3.5

Please include below any other applicable logs and screenshots that show your problem:

grafik

grafik

beerose commented 2 years ago

Hi @Kiodok! I think there are two issues:

  1. Missing Blitz session middleware — yet to investigate.
  2. Failed to load script ... in the browser — are you using <Link> component? If yes, you should use <a> instead. We had a similar issue here: https://github.com/blitz-js/legacy-framework/issues/221, and it seemed to help.
Kiodok commented 2 years ago

Hello @beerose :) With your advice from the second step, I was able to fix the error shown in the second screenshot from above. Missing Blitz sessionMiddleware is sadly the same.

Thanks for your help so far 👍

beerose commented 2 years ago

hey @Kiodok, I was trying to reproduce it and passport-twitch-strategy seems to work fine, so maybe the problem is somewhere else. Could you share your blitz.config.ts?

Kiodok commented 2 years ago

Hey @beerose :D That sounds great so far, thanks for trying it out.

blitz.config.ts:

import { BlitzConfig, sessionMiddleware, simpleRolesIsAuthorized } from "blitz"

const config: BlitzConfig = {
  middleware: [
    sessionMiddleware({
      cookiePrefix: "streamconnect",
      isAuthorized: simpleRolesIsAuthorized,
    }),
  ],

  webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
    // Note: we provide webpack above so you should not `require` it
    // Perform customizations to webpack config
    // Important: return the modified config
    module.exports = {
      distDir: "build",
    };
    return config
  },
}
module.exports = config
Kiodok commented 2 years ago

Hello @beerose :) Did you find out anything new about the sessionMiddleware error?

Greetings, Kiodok

beerose commented 2 years ago

Hey @Kiodok — could you try using <a> HTML element instead of router.push and see if that works? Something like this:

<a href="api/auth/twitch">
  Login with Twitch
</a>
Kiodok commented 2 years ago

Hello @beerose, Yes, I tried it, but nothing changed.

<a href="/api/auth/twitch">
  <SignUpInButton color="deepPurple">Twitch</SignUpInButton>
</a>
beerose commented 2 years ago

Ok, I tried it again, and this time I used your blitz.config.ts. You overode the config (with the second module.exports and there was no session config. You'll have to set distDir in the first object:

import { BlitzConfig, sessionMiddleware, simpleRolesIsAuthorized } from "blitz"

const config: BlitzConfig = {
  middleware: [
    sessionMiddleware({
      cookiePrefix: "streamconnect",
      isAuthorized: simpleRolesIsAuthorized,
    }),
  ],
  distDir: "build",

  webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
    // Note: we provide webpack above so you should not `require` it
    // Perform customizations to webpack config
    // Important: return the modified config
    return config
  },
}
module.exports = config
Kiodok commented 2 years ago

Thanks @beerose, that really helped and did the trick so far. Now I get some profile information like ID and name from my twitch account. But after that I got a new error:

14:02:51.173 INFO Starting authentication via twitch... Starting authentication via twitch... 14:02:51.978 INFO Processing callback for twitch... Processing callback for twitch... API resolved without sending a response for /api/auth/twitch/callback?code=mmgfj5cfosnxxeod8x2b3rq7no57ma&scope=, this may result in stalled requests. { userId: '79175660', userName: 'kiodok' } Error: Cannot find module 'F:\Blitz Projects\streamconnect.next\serverless\blitz-db.js' Require stack:

I already searched for the module serverless\blitz-db.js, but couldn't find anything.

grafik

beerose commented 2 years ago

Sorry about the late reply. The code that looks for blitz-db.js is here: https://github.com/blitz-js/blitz/blob/canary/nextjs/packages/next/stdlib-server/auth-sessions.ts#L66, but I'm not yet sure why it's causing issues. It should look under server/blitz-db.js but it turns out to be empty. Maybe you could put some console logs in node_modules to debug this? I'll try to reproduce it too.

Kiodok commented 2 years ago

@beerose No problem. I think the problem is, that my .next folder is missing. In the past it was generated with blitz build, but that doesn't happen anymore. It can't find the file within F:\Blitz Projects\streamconnect.next\serverless\blitz-db.js without the folder at all. The question is now, how to generate the .next folder :D

beerose commented 2 years ago

Hmm, that should be generated out of the box when you run blitz dev or blitz build. Could you try reinstalling deps and running one of those commands again? Or do you remember when it stopped being generated?

Kiodok commented 2 years ago

@beerose I reinstalled everything and ran both commands - same error. I'm not sure when it stopped being generated, but I think it was when I changed the distDir in blitz.config.ts. But it's still the version you commented a few days ago.

import { BlitzConfig, sessionMiddleware, simpleRolesIsAuthorized } from "blitz"

const config: BlitzConfig = {
  middleware: [
    sessionMiddleware({
      cookiePrefix: "streamconnect",
      isAuthorized: simpleRolesIsAuthorized,
    }),
  ],
  distDir: "build",

  webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
    // Note: we provide webpack above so you should not `require` it
    // Perform customizations to webpack config
    // Important: return the modified config
    return config
  },
}
module.exports = config
beerose commented 2 years ago

Ah okay. So since you have build instead of .next and it looks for .next, it can't find anything. The issue is that this code: https://github.com/blitz-js/blitz/blob/canary/nextjs/packages/next/stdlib-server/auth-sessions.ts#L66, doesn't respect custom distDir. I suppose if you remove distDir (so you'll have .next back), it will work.

Kiodok commented 2 years ago

@beerose I removed the distDir and now I get the following error:

API resolved without sending a response for /api/auth/twitch/callback?code=vtxuqhnsgtbb153vabw99t1765xtms&scope=user%3Aread%3Aemail, this may result in stalled requests. { userId: '79175660', userName: 'kiodok', userEmail: 'kaka22-kiodok@web.de' } PrismaClientValidationError: Invalid prisma.session.create() invocation:

{ data: { expiresAt: new Date('2022-01-09T00:31:55.889Z'), handle: 'YUCejVvO0m25zlVWga84PjhvAXT-Xl1M:ots', userId: undefined, hashedSessionToken: 'a8a992acf0c90ef119bb1eef2e5903344212d601a09046a0d0edc1e63476ba09', antiCSRFToken: '0BQsDWRqIbx0cw3REjOqpQxLIL242UhQ', publicData: '{"userId":"79175660","userName":"kiodok","userEmail":"kaka22-kiodok@web.de"}', privateData: '{}', user: {


      connect: {
        id: '79175660'
      }
    }
  }
}

Unknown arg `user` in data.user for type SessionUncheckedCreateInput. Did you mean `userId`? Available args:
type SessionUncheckedCreateInput {
  id?: Int
  createdAt?: DateTime
  updatedAt?: DateTime
  expiresAt?: DateTime | Null
  handle: String
  hashedSessionToken?: String | Null
  antiCSRFToken?: String | Null
  publicData?: String | Null
  privateData?: String | Null
  userId?: Int | Null
}

    at Document.validate (F:\Blitz Projects\streamconnect\node_modules\@prisma\client\runtime\index.js:35616:19)
    at PrismaClient._executeRequest (F:\Blitz Projects\streamconnect\node_modules\@prisma\client\runtime\index.js:38003:17)
    at consumer (F:\Blitz Projects\streamconnect\node_modules\@prisma\client\runtime\index.js:37948:23)
    at F:\Blitz Projects\streamconnect\node_modules\@prisma\client\runtime\index.js:37950:47
    at AsyncResource.runInAsyncScope (async_hooks.js:197:9)
    at PrismaClient._request (F:\Blitz Projects\streamconnect\node_modules\@prisma\client\runtime\index.js:37950:25)
    at request (F:\Blitz Projects\streamconnect\node_modules\@prisma\client\runtime\index.js:38053:77)
    at _callback (F:\Blitz Projects\streamconnect\node_modules\@prisma\client\runtime\index.js:38258:14)
    at PrismaPromise.then (F:\Blitz Projects\streamconnect\node_modules\@prisma\client\runtime\index.js:38265:23) {
  clientVersion: '3.1.1'
}

What do you think about this?
Thanks for your help so far :) I really appreciate that
Kiodok commented 2 years ago

@beerose It's working now! :D Thanks for your time and helpful advices. I just needed to add the code for db.user.create.

beerose commented 2 years ago

Awesome, @Kiodok!

I just needed to add the code for db.user.create.

Do you mean in the strategy callback?

Kiodok commented 2 years ago

Yes, exactly.

beerose commented 2 years ago

ok, thanks!