Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'canary' into fix-dynamic-middleware-routing.patch
- Loading branch information
Showing
51 changed files
with
1,312 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# The two iron-session values may be left as-is while testing out this example app. | ||
IRON_SESSION_COOKIE_NAME="stytch_next_example_cookie" | ||
IRON_SESSION_PASSWORD="complex_password_at_least_32_characters_long" | ||
# The below values may be found in your Stytch Dashboard: https://stytch.com/dashboard/api-keys | ||
STYTCH_PROJECT_ENV=test | ||
STYTCH_PROJECT_ID="YOUR_STYTCH_PROJECT_ID" | ||
STYTCH_SECRET="YOUR_STYTCH_SECRET" | ||
NEXT_PUBLIC_STYTCH_PUBLIC_TOKEN="YOUR_STYTCH_PUBLIC_TOKEN" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
*.pem | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# local env files | ||
.env.local | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
|
||
# vercel | ||
.vercel |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
# Stytch + Next.js example app on Vercel | ||
|
||
This is a [Stytch](https://stytch.com) + [Next.js](https://nextjs.org/) project that showcases how to enable elegant authentication in your applicaiton. | ||
|
||
<p align="center"><img src="./public/example-app-image.png" alt="stytch" width="50%"/></p> | ||
|
||
In this repo, we have two sample auth flows: | ||
|
||
- SDK integration: This flow uses Stytch's React component to create a login and sign-up flow using [Email Magic Links](https://stytch.com/docs/api/send-by-email). | ||
- API integration: This flow uses a custom UI with Stytch's backend API for [Onetime Passcodes(OTP) via SMS](https://stytch.com/docs/api/sms-otp-overview) authentication. | ||
|
||
Both flows use Stytch's [Node client library](https://github.com/stytchauth/stytch-node) and [`iron-session`](https://github.com/vvo/next-iron-session) for session management. | ||
|
||
**Note:** By default this example app enables three of our OAuth providers, Google, Microsoft, and Apple. If you haven't set up these OAuth providers in your [Dashboard](https://stytch.com/dashboard/oauth), you'll receive a redirect error when you attempt to login via those providers. You may remove all OAuth methods by removing `SDKProductTypes.oauth` from the `products` array in [pages/index.tsx](pages/index.tsx) or adjust which ones are displayed by via `oauthOptions.providers` in the same file. More detail on working with OAuth providers in our SDK may be found in our [Docs](https://stytch.com/docs/javascript-sdk#javascript-sdk/oauth). | ||
|
||
# Deploy on Vercel | ||
|
||
## Setting up Stytch | ||
|
||
The first step is to configure the appropriate redirect URLs for your project. You'll set these magic link redirect URLs in the [Redirect URLs](https://stytch.com/dashboard/redirect-urls) section of your Dashboard. Add `https://*.vercel.app:3000` as both a login and sign-up redirect URL. | ||
|
||
## Running the example app | ||
|
||
Now just click the deploy button below! Once you're signed in to your Vercel account, you'll be guided through how to get up and running quickly. Check out [.env.template](/.env.template) for pointers on filling in the appropriate environment variables for this step. | ||
|
||
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fnext.js%2Fblob%2Fcanary%2Fexamples%2Fauth-with-stytch%2F&env=STYTCH_PROJECT_ENV,STYTCH_PROJECT_ID,STYTCH_SECRET,NEXT_PUBLIC_STYTCH_PUBLIC_TOKEN,IRON_SESSION_PASSWORD,IRON_SESSION_COOKIE_NAME&envDescription=All%20variables%20here%20need%20values%2C%20see%20the%20following%20link%20for%20pointers%20on%20how%20to%20feel%20these%20out.&envLink=https%3A%2F%2Fgithub.com%2Fvercel%2Fnext.js%2Fblob%2Fcanary%2Fexamples%2Fauth-with-stytch%2F.env.template&project-name=stytch-nextjs-vercel&repo-name=stytch-nextjs-vercel&demo-title=Stytch%20on%20Next.js%20with%20Vercel&demo-description=Next.js%20example%20app%20using%20Stytch%20authentication&demo-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fnext.js%2Fblob%2Fcanary%2Fexamples%2Fauth-with-stytch&demo-image=https%3A%2F%2Fstytch.com%2Flogo-preview.png) | ||
|
||
# Running locally via `vercel dev` | ||
|
||
## Setting up Stytch | ||
|
||
After signing up for Stytch, you'll need your Project's `project_id`, `secret`, and `public_token`. You can find these in the [API keys tab](https://stytch.com/dashboard/api-keys). | ||
|
||
Once you've gathered these values, add them to a new .env.local file. | ||
Example: | ||
|
||
```bash | ||
cp .env.template .env.local | ||
# Replace your keys in new .env.local file | ||
``` | ||
|
||
Next we'll configure the appropriate redirect URLs for your project, you'll set these magic link URLs for your project in the [Redirect URLs](https://stytch.com/dashboard/redirect-urls) section of your Dashboard. Add `http://localhost:3000/api/authenticate_magic_link` as both a login and sign-up redirect URL. | ||
|
||
## Running the example app | ||
|
||
Install dependencies by running | ||
|
||
```bash | ||
npm install | ||
# or | ||
yarn install | ||
``` | ||
|
||
You can then run a development server using: | ||
|
||
```bash | ||
vercel dev | ||
``` | ||
|
||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. | ||
|
||
## Documentation | ||
|
||
Learn more about some of Stytch's products used in this example app: | ||
|
||
- [Stytch React](https://www.npmjs.com/package/@stytch/stytch-react) | ||
- [Stytch's node client library](https://www.npmjs.com/package/stytch) | ||
- [iron-session](https://github.com/vvo/next-iron-session) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import React from 'react' | ||
import styles from '../styles/Home.module.css' | ||
import { LoginMethod } from '../lib/types' | ||
import StytchContainer from './StytchContainer' | ||
|
||
type Props = { | ||
setLoginMethod: (loginMethod: LoginMethod) => void | ||
} | ||
|
||
const LoginEntryPoint = (props: Props) => { | ||
const { setLoginMethod } = props | ||
return ( | ||
<StytchContainer> | ||
<h2>Hello Vercel!</h2> | ||
<p className={styles.entrySubHeader}> | ||
This example app demonstrates how you can integrate with Stytch using | ||
Next.js and deploy on Vercel. Now, let’s get started! | ||
</p> | ||
<button | ||
className={styles.entryButton} | ||
onClick={() => setLoginMethod(LoginMethod.SDK)} | ||
> | ||
SDK Integration (Email magic links) | ||
</button> | ||
<button | ||
className={styles.entryButton} | ||
onClick={() => setLoginMethod(LoginMethod.API)} | ||
> | ||
API Integration (SMS Passcodes) | ||
</button> | ||
</StytchContainer> | ||
) | ||
} | ||
|
||
export default LoginEntryPoint |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import React, { useState } from 'react' | ||
import SendOTPForm from './SendOTPForm' | ||
import VerifyOTPForm from './VerifyOTPForm' | ||
import StytchContainer from './StytchContainer' | ||
|
||
const LoginWithSMS = () => { | ||
const [otpSent, setOTPSent] = useState(false) | ||
const [phoneNumber, setPhoneNumber] = useState('') | ||
const [methodId, setMethodId] = useState('') | ||
|
||
return ( | ||
<StytchContainer> | ||
{!otpSent ? ( | ||
<SendOTPForm | ||
phoneNumber={phoneNumber} | ||
setMethodId={setMethodId} | ||
setOTPSent={setOTPSent} | ||
setPhoneNumber={setPhoneNumber} | ||
/> | ||
) : ( | ||
<VerifyOTPForm methodId={methodId} phoneNumber={phoneNumber} /> | ||
)} | ||
</StytchContainer> | ||
) | ||
} | ||
|
||
export default LoginWithSMS |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import React from 'react' | ||
import { sendOTP } from '../lib/otpUtils' | ||
import styles from '../styles/Home.module.css' | ||
|
||
type Props = { | ||
phoneNumber: string | ||
setMethodId: (methodId: string) => void | ||
setOTPSent: (submitted: boolean) => void | ||
setPhoneNumber: (phoneNumber: string) => void | ||
} | ||
|
||
const SendOTPForm = (props: Props): JSX.Element => { | ||
const { phoneNumber, setMethodId, setOTPSent, setPhoneNumber } = props | ||
const [isDisabled, setIsDisabled] = React.useState(true) | ||
|
||
const isValidNumber = (phoneNumberValue: string) => { | ||
// Regex validates phone numbers in (xxx)xxx-xxxx, xxx-xxx-xxxx, xxxxxxxxxx, and xxx.xxx.xxxx format | ||
const regex = /^[(]?[0-9]{3}[)]?[-s.]?[0-9]{3}[-s.]?[0-9]{4}$/g | ||
if (phoneNumberValue.match(regex)) { | ||
return true | ||
} | ||
return false | ||
} | ||
|
||
const onPhoneNumberChange = (e: React.ChangeEvent<{ value: string }>) => { | ||
setPhoneNumber(e.target.value) | ||
if (isValidNumber(e.target.value)) { | ||
setIsDisabled(false) | ||
} else { | ||
setIsDisabled(true) | ||
} | ||
} | ||
|
||
const onSubmit = async (e: React.FormEvent) => { | ||
e.preventDefault() | ||
if (isValidNumber(phoneNumber)) { | ||
const methodId = await sendOTP(phoneNumber) | ||
setMethodId(methodId) | ||
setOTPSent(true) | ||
} | ||
} | ||
|
||
return ( | ||
<div> | ||
<h2>Enter phone number</h2> | ||
<p className={styles.smsInstructions}> | ||
Enter your phone number to receive a passcode for authentication. | ||
</p> | ||
<form onSubmit={onSubmit}> | ||
<div className={styles.telInput}> | ||
<input | ||
className={styles.flag} | ||
name="intlCode" | ||
type="text" | ||
value="+1" | ||
readOnly | ||
/> | ||
<input | ||
id={styles.phoneNumber} | ||
className={styles.phoneNumber} | ||
placeholder="(123) 456-7890" | ||
value={phoneNumber} | ||
onChange={onPhoneNumberChange} | ||
type="tel" | ||
/> | ||
</div> | ||
<p className={styles.smsDisclaimer}> | ||
By continuing, you consent to receive an SMS for verification. Message | ||
and data rates may apply. | ||
</p> | ||
<input | ||
className={styles.primaryButton} | ||
disabled={isDisabled} | ||
id="button" | ||
type="submit" | ||
value="Continue" | ||
/> | ||
</form> | ||
</div> | ||
) | ||
} | ||
|
||
export default SendOTPForm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import React from 'react' | ||
import styles from '../styles/Home.module.css' | ||
import Image from 'next/image' | ||
import lockup from '/public/powered-by-stytch.svg' | ||
|
||
type Props = { | ||
children: React.ReactElement | React.ReactElement[] | ||
} | ||
|
||
const StytchContainer = (props: Props) => { | ||
const { children } = props | ||
return ( | ||
<div className={styles.container}> | ||
<div>{children}</div> | ||
<Image alt="Powered by Stytch" height={15} src={lockup} width={150} /> | ||
</div> | ||
) | ||
} | ||
|
||
export default StytchContainer |
Oops, something went wrong.