https://supertokens.com/ logo
e

EdwinN1337

05/20/2022, 10:36 AM
Hi guys, trying to explore if supertokens is the right solution for us. right now we have our own
authentication
solution but we are searching for a more secure solution with session management 😉 the only thing whats not really clear for me, if we can use our existing UI. We have a multistep register form build with chakra-ui/react-hook-form?
n

nkshah2

05/20/2022, 10:37 AM
Hi @EdwinN1337 , Yes you can use your own UI and call our APIs manually to achieve this
e

EdwinN1337

05/20/2022, 10:45 AM
Great! 💪 Guess I overlooked in docs theb
Couldn't find it
n

nkshah2

05/20/2022, 10:54 AM
In the docs for frontend there should be an option for Plain Javascript which points out how to use SuperTokens with custom UI
e

EdwinN1337

05/20/2022, 11:37 AM
There is no recipe/guide available right?
thanks!
n

nkshah2

05/20/2022, 11:45 AM
@EdwinN1337 You can follow the docs by selecting the recipe you want to use on this page: https://supertokens.com/docs/guides
e

EdwinN1337

05/20/2022, 2:38 PM
I'm trying to get a custom UI going i've got a nextjs app > followed the docs all good
Inside the emailpassword recipe, im trying to log the input / response
to see if all works
Not sure what i'm doing wrong, but it seems like this is not called
there are the endpoint I can use right? for email/password
i've tried
rid=emailpassword
no luck either
n

nkshah2

05/21/2022, 2:08 AM
So rid should definitely be emailpassword. Can you try throwing an error from inside the signInPOST function and see if that works correctly? Just to first make sure that the function is being called
Also can you post the code for where you call supertokens.init for the backend config?
e

EdwinN1337

05/23/2022, 8:11 AM
Ah, it works sorry! Probably misspelled
rid
Thanks!
n

nkshah2

05/23/2022, 8:12 AM
Happy to help
e

EdwinN1337

05/23/2022, 10:39 AM
Another question, can't find it in the docs
Copy code
js
 Passwordless.init({
        flowType: 'MAGIC_LINK',
        contactMethod: 'EMAIL',
        validateEmailAddress: async (email) => {
          //validate email
          console.log('validateEmailAddress', email)

          return 'OK'
        },
        createAndSendCustomEmail: async ({ email, urlWithLinkCode }) => {
          await sendEmail({
            to: email,
            emailMarkup: emailMarkup({ url: urlWithLinkCode }),
            subject: 'Inloggen bij De Lokalist',
          })
        },
      }),
The validateEmailAddress method is called before createAndSendCustomEmail
But I have no clue, what the response should be when e-mail is validated
n

nkshah2

05/23/2022, 10:55 AM
Ah right, yes the documentation doesnt make it clear. So
validateEmailAddress
returns a
string
or
undefined
. If you return a
string
the SDK assumes there was a validation error and uses the string as the error message. Returning
undefined
means that the email is valid
e

EdwinN1337

05/23/2022, 11:29 AM
thanks again 😄
loving it sofart
n

nkshah2

05/23/2022, 11:29 AM
🙌
Thanks! We appreciate it
e

EdwinN1337

05/23/2022, 11:46 AM
Hmm, so i've got the validation and sending email with magic link working> When I click on the magic link: http://localhost:4000/api/auth/verify?rid=passwordless&preAuthSessionId=mRd5fGLxSP_TeV2GjQDLmXbrtzIELZ15JkBKdDJ0UbA=#ocu9zA6u873CqmheofK0eXzNFncEgwC4tE0v9Il44ys= What is the next step? Docs is unclear about that
n

nkshah2

05/23/2022, 11:48 AM
Can you enable logging and send us the output here. You can refer to the troubleshooting guide to know how to do that: https://supertokens.com/docs/emailpassword/troubleshooting/how-to-troubleshoot
e

EdwinN1337

05/23/2022, 11:50 AM
ahh
022-05-23T11:49:53.465Z com.supertokens {t: "2022-05-23T11:49:53.465Z", message: "middleware: Not handling because no recipe matched", file: `
makes sence, i switched to passwordless (got a dashboard app running with magic.link)
n

nkshah2

05/23/2022, 11:50 AM
Can you post the full logs? (including logs generated when your server started)
e

EdwinN1337

05/23/2022, 11:52 AM
Copy code
dashboard:dev: 2022-05-23T11:49:53.446Z com.supertokens {t: "2022-05-23T11:49:53.446Z", message: "session init: refreshTokenPath: /api/auth/session/refresh", file: "C:\Users\edwin\Desktop\Projects\lokalist-monorepo-v2\node_modules\supertokens-node\lib\build\recipe\session\recipe.js:168:18" sdkVer: "9.2.1"}dashboard:dev: 2022-05-23T11:49:53.446Z com.supertokens {t: "2022-05-23T11:49:53.446Z", message: "session init: sessionExpiredStatusCode: 401", file: "C:\Users\edwin\Desktop\Projects\lokalist-monorepo-v2\node_modules\supertokens-node\lib\build\recipe\session\recipe.js:171:18" sdkVer: "9.2.1"}dashboard:dev: 2022-05-23T11:49:53.463Z com.supertokens {t: "2022-05-23T11:49:53.463Z", message: "middleware: Started", file: "C:\Users\edwin\Desktop\Projects\lokalist-monorepo-v2\node_modules\supertokens-node\lib\build\supertokens.js:158:26" sdkVer: "9.2.1"}
dashboard:dev: 2022-05-23T11:49:53.464Z com.supertokens {t: "2022-05-23T11:49:53.464Z", message: "middleware: requestRID is: undefined", file: "C:\Users\edwin\Desktop\Projects\lokalist-monorepo-v2\node_modules\supertokens-node\lib\build\supertokens.js:172:26" sdkVer: "9.2.1"}dashboard:dev: 2022-05-23T11:49:53.464Z com.supertokens {t: "2022-05-23T11:49:53.464Z", message: "middleware: Checking recipe ID for match: passwordless", file: "C:\Users\edwin\Desktop\Projects\lokalist-monorepo-v2\node_modules\supertokens-node\lib\build\supertokens.js:220:34" sdkVer: "9.2.1"}
dashboard:dev: 2022-05-23T11:49:53.465Z com.supertokens {t: "2022-05-23T11:49:53.465Z", message: "middleware: Not handling because no recipe matched", file: "C:\Users\edwin\Desktop\Projects\lokalist-monorepo-v2\node_modules\supertokens-node\lib\build\supertokens.js:243:30" sdkVer: "9.2.1"}
n

nkshah2

05/23/2022, 11:54 AM
There should be more logs on server start. You should see something along the lines of
Started SuperTokens with debug logging (supertokens.init called)
e

EdwinN1337

05/23/2022, 11:54 AM
ah ye here's the full one
here
n

nkshah2

05/23/2022, 11:58 AM
So a few things: -
"apiBasePath":"/api/auth","websiteBasePath":"api/auth"
You shouldnt use the same base paths for both the website and the api layer since you are using NextJs - The
rid
header in the request headers should match the recipe you are trying to use - Once you click on the magic link, on your frontend you will need to call the
/consume
route for Passwordless (https://app.swaggerhub.com/apis/supertokens/FDI/1.13.2#/Passwordless%20Recipe/passwordlessSignInUpConsume). The API expects a
linkCode
which is the location hash after you click on the magic link
e

EdwinN1337

05/23/2022, 12:01 PM
ahh, clear... the /consume, best would be to use some kind of polling right?
wait for the link to be clicked
n

nkshah2

05/23/2022, 12:02 PM
Yep, that will prevent automatic calls to your APIs if a mail client opens the URL internally (which is likely)
So the link will open the
/auth/verify
route on your frontend. That route can have a button "Confirm" or something similar and then when the user clicks it you can call the
/consume
API
e

EdwinN1337

05/23/2022, 12:06 PM
ah right! and how do I get the
linkCode
? (not really sure if I get that)
ah nvm
got it
😉
e

EdwinN1337

05/23/2022, 12:09 PM
any specific thing I have to do here? Or I can leave it to the defaults...
getLinkDomainAndPath
n

nkshah2

05/23/2022, 12:10 PM
Ill need a little more context, where are you trying to add this?
e

EdwinN1337

05/23/2022, 12:10 PM
ah its changing the magic link url,
sometimes i have to click more in the docs before asking 😉
I'll try it out again! thnx
n

nkshah2

05/23/2022, 12:11 PM
Happy to help, feel free to ask questions if you have them 🙂
e

EdwinN1337

05/23/2022, 12:13 PM
Will do!
- Once you click on the magic link, on your frontend you will need to call the /consume route for Passwordless (https://app.swaggerhub.com/apis/supertokens/FDI/1.13.2#/Passwordless%20Recipe/passwordlessSignInUpConsume). The API expects a linkCode which is the location hash after you click on the magic link
Blegh, not sure if I get this right > shouldnt the middleware handle this link and redirect / close browser?
i cant override
/api/auth/verify
Where do I build
Confirm
button?
n

nkshah2

05/23/2022, 12:39 PM
Right so the magic link is actually meant for your frontend, not your backend (Basically when the user clicks the link on their email, they need to be redirected somewhere)
Which means that the user would land on your website on some page with the path
/auth/verify
. On this page you can have a button that the user will click and then you will need to call the API manually
e

EdwinN1337

05/23/2022, 12:40 PM
ah but the path is
/api/auth/verify?
it shouild be
auth/verify
n

nkshah2

05/23/2022, 12:41 PM
The path is
/api/
because your
websiteBasePath
is
/api/auth
Which is what I meant by you shouldnt use the same base paths for both your api and website
If you change the website base path then the magic link will use that instead
e

EdwinN1337

05/23/2022, 12:43 PM
yeah i did change it, weird
Copy code
js
 appName: 'Lokalist Dashboard',
  apiDomain: process.env.NEXT_PUBLIC_FRONTEND_URL,
  websiteDomain: process.env.NEXT_PUBLIC_FRONTEND_URL,
  apiBasePath: '/api/auth',
  websiteBasePath: '/auth',
thats why i was confused, i cant change the
api/auth
n

nkshah2

05/23/2022, 12:44 PM
So in the logs you sent earlier, when you call SuperTokens.init in your API layer you are passing
apiBasePath:"/api/auth",websiteBasePath:"api/auth"
I would double check that
e

EdwinN1337

05/23/2022, 12:45 PM
I've changed that, restarted server
dashboard:dev: 2022-05-23T12:44:10.053Z com.supertokens {t: "2022-05-23T12:44:10.053Z", message: "appInfo: {"appName":"Lokalist Dashboard","apiDomain":"http://localhost:4000","websiteDomain":"http://localhost:4000","apiBasePath":"/api/auth","websiteBasePath":"/auth"}",
ah nice
n

nkshah2

05/23/2022, 12:46 PM
I mean in this step
e

EdwinN1337

05/23/2022, 12:46 PM
yeah, the problem is
u have to restart server
woops
with nextjs,
n

nkshah2

05/23/2022, 12:46 PM
Ah :p Happens to the best of us
e

EdwinN1337

05/23/2022, 12:46 PM
thanks!
n

nkshah2

05/23/2022, 12:46 PM
Well, now if you trigger the email then the URL should use
/auth
and not
/api/auth
Happy to help
e

EdwinN1337

05/23/2022, 12:49 PM
after this is done, we swapped our
magic.link
implementation from our dashboard to > supertokens what's left is to replace custom auth from our ios/android/web apps (monorepo; capacitor / nextjs / hasura) stack
i might come back with some questions due to custom UI 😉
n

nkshah2

05/23/2022, 12:49 PM
Ah awesome! And yep feel free to ask them. We do have docs for web with Hasura as well if you need them
e

EdwinN1337

05/23/2022, 12:50 PM
i saw > only "problem" which might occur is that supertokens is using httpOnly cookies & interceptors on the web we use fetch
but on our capacitor apps, we need to use the native
http
plugin, (so no fetch or axios)
if we want to use session cookies / httpOnly
but confident willl figure our
out*
n

nkshah2

05/23/2022, 12:52 PM
Ah right, let us know if you need help with anything there
e

EdwinN1337

05/23/2022, 1:17 PM
Is this the linkcode?
n

nkshah2

05/23/2022, 1:17 PM
Everything after the
#
yes. You can use
window.location.hash
to access it easily
e

EdwinN1337

05/23/2022, 1:17 PM
ah ;d
n

nkshah2

05/23/2022, 1:18 PM
Make sure to remove the
#
symbol before sending it to the API
e

EdwinN1337

05/23/2022, 1:53 PM
Works 🙂 What's the exact flow for frontend? Do I have to query
/{apiBasePath}/signup/email/exists
? Wait for response to have
STATUS=OK, EXIST=true
and if so, i can start using
import {getUserId, doesSessionExist} from 'supertokens-website'
?
have to listen to some event, to know user clicked on button and is logged in
n

nkshah2

05/23/2022, 1:59 PM
Not sure what you mean by flow, do you mean what to do after signing in?
doesSessionExist
is available to use at any time, after the sign in/up process is complete the function will return true
e

EdwinN1337

05/23/2022, 2:08 PM
ye i ment something like this
Copy code
js
  const { data } = useQuery(['session'], doesSessionExist, {
    enabled: isSubmitting,
    refetchInterval: 1000,
    onSuccess: (data) => {
      if (data) {
        setIsSubmitting(false)
      }
    },
  })
n

nkshah2

05/23/2022, 2:10 PM
I’m not familiar with the syntax but it would work similar to any other async operation If your logic needs an active session then you’d check for it before performing it
3 Views