Skip to content

Commit

Permalink
Add authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
baptisteArno committed Nov 29, 2021
1 parent 68dd491 commit 5e14a94
Show file tree
Hide file tree
Showing 51 changed files with 5,067 additions and 121 deletions.
10 changes: 10 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
root = true

[*]
end_of_line = lf
insert_final_newline = true

[*.{js,json,yml}]
charset = utf-8
indent_style = space
indent_size = 2
27 changes: 27 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
DATABASE_URL=postgresql://username:password@host:5450/typebot?schema=public

# Used for email auth and email notifications
EMAIL_SERVER_USER=username
EMAIL_SERVER_PASSWORD=password
EMAIL_SERVER_HOST=smtp.example.com
EMAIL_SERVER_PORT=587
EMAIL_FROM=[email protected]

# AUTH
# (Optional) Used to login using GitHub
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=

# (Optional) Used to login using Google
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=

# (Optional) Used to login using Facebook
FACEBOOK_CLIENT_ID=
FACEBOOK_CLIENT_SECRET=

# Used for uploading images, videos, etc...
S3_UPLOAD_KEY=
S3_UPLOAD_SECRET=
S3_UPLOAD_REGION=
S3_UPLOAD_BUCKET=
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,10 @@ node_modules

.next

.env
.env.local

cypress.env.json



64 changes: 59 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,60 @@
# Getting Started
<div align="center">
<h1>Typebot</h1>
<a href="https://github.com/prisma/prisma/blob/main/CONTRIBUTING.md"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" /></a>
<a href="https://github.com/prisma/prisma/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-AGPL-blue" /></a>
<br />
<a href="https://docs.typebot.io">Quickstart</a>
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
<a href="https://www.typebot.io/">Website</a>
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
<a href="https://docs.typebot.io">Docs</a>
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
<a href="https://www.typebot.io/blog">Blog</a>
<span>&nbsp;&nbsp;&nbsp;&nbsp;</span>
<a href="https://twitter.com/Typebot_io">Twitter</a>
<br />
<hr />
</div>

```sh
yarn set version berry
yarn install
```
## Development (localhost)

1. Clone the repo

```sh
git clone https://github.com/Typebot-io/typebot.git
```

2. Install packages with yarn

```sh
yarn set version berry
yarn install
```

3. Copy `.env.example` to `.env`
4. Configure environment variables in the `.env` file.
5. Setup the database

```sh
yarn dev:setup
```

6. Run the applications

```sh
yarn dev:builder
```

```sh
yarn dev:viewer
```

7. Open [Prisma Studio](https://www.prisma.io/studio) to look at or modify the database content

```sh
yarn db:inspect
```

## Deployment

TO-DO
32 changes: 32 additions & 0 deletions apps/builder/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module.exports = {
ignorePatterns: ['node_modules'],
env: {
browser: true,
es6: true,
},
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:react/recommended',
'next/core-web-vitals',
'prettier',
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
sourceType: 'module', // Allows for the use of imports
ecmaFeatures: {
jsx: true, // Allows for the parsing of JSX
},
},
settings: {
react: {
version: 'detect', // Tells eslint-plugin-react to automatically detect the version of React to use
},
},
plugins: ['prettier', 'react', 'cypress', '@typescript-eslint'],
rules: {
'react/no-unescaped-entities': [0],
'prettier/prettier': 'error',
'react/display-name': [0],
},
}
1 change: 1 addition & 0 deletions apps/builder/assets/icons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import { IconProps, Icon } from '@chakra-ui/react'
69 changes: 69 additions & 0 deletions apps/builder/assets/logos.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { IconProps, Icon } from '@chakra-ui/react'

export const TypebotLogo = ({
isDark,
...props
}: { isDark?: boolean } & IconProps) => (
<Icon viewBox="0 0 500 500" w="50px" h="50px" {...props}>
<rect
width="500"
height="500"
rx="75"
fill={isDark ? 'white' : '#0042DA'}
/>
<rect
x="438.709"
y="170.968"
width="64.5161"
height="290.323"
rx="32.2581"
transform="rotate(90 438.709 170.968)"
fill="#FF8E20"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M93.5481 235.484C111.364 235.484 125.806 221.041 125.806 203.226C125.806 185.41 111.364 170.968 93.5481 170.968C75.7325 170.968 61.29 185.41 61.29 203.226C61.29 221.041 75.7325 235.484 93.5481 235.484Z"
fill="#FF8E20"
/>
<rect
x="61.29"
y="332.259"
width="64.5161"
height="290.323"
rx="32.2581"
transform="rotate(-90 61.29 332.259)"
fill={isDark ? '#0042DA' : 'white'}
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M406.451 267.742C388.635 267.742 374.193 282.184 374.193 300C374.193 317.815 388.635 332.258 406.451 332.258C424.267 332.258 438.709 317.815 438.709 300C438.709 282.184 424.267 267.742 406.451 267.742Z"
fill={isDark ? '#0042DA' : 'white'}
/>
</Icon>
)

export const GithubLogo = (props: IconProps) => (
<Icon viewBox="0 0 512 512" {...props}>
<title>{'Logo Github'}</title>
<path d="M256 32C132.3 32 32 134.9 32 261.7c0 101.5 64.2 187.5 153.2 217.9a17.56 17.56 0 003.8.4c8.3 0 11.5-6.1 11.5-11.4 0-5.5-.2-19.9-.3-39.1a102.4 102.4 0 01-22.6 2.7c-43.1 0-52.9-33.5-52.9-33.5-10.2-26.5-24.9-33.6-24.9-33.6-19.5-13.7-.1-14.1 1.4-14.1h.1c22.5 2 34.3 23.8 34.3 23.8 11.2 19.6 26.2 25.1 39.6 25.1a63 63 0 0025.6-6c2-14.8 7.8-24.9 14.2-30.7-49.7-5.8-102-25.5-102-113.5 0-25.1 8.7-45.6 23-61.6-2.3-5.8-10-29.2 2.2-60.8a18.64 18.64 0 015-.5c8.1 0 26.4 3.1 56.6 24.1a208.21 208.21 0 01112.2 0c30.2-21 48.5-24.1 56.6-24.1a18.64 18.64 0 015 .5c12.2 31.6 4.5 55 2.2 60.8 14.3 16.1 23 36.6 23 61.6 0 88.2-52.4 107.6-102.3 113.3 8 7.1 15.2 21.1 15.2 42.5 0 30.7-.3 55.5-.3 63 0 5.4 3.1 11.5 11.4 11.5a19.35 19.35 0 004-.4C415.9 449.2 480 363.1 480 261.7 480 134.9 379.7 32 256 32z" />
</Icon>
)

export const GoogleLogo = (props: IconProps) => (
<Icon viewBox="0 0 512 512" {...props}>
<title>{'Logo Google'}</title>
<path d="M473.16 221.48l-2.26-9.59H262.46v88.22H387c-12.93 61.4-72.93 93.72-121.94 93.72-35.66 0-73.25-15-98.13-39.11a140.08 140.08 0 01-41.8-98.88c0-37.16 16.7-74.33 41-98.78s61-38.13 97.49-38.13c41.79 0 71.74 22.19 82.94 32.31l62.69-62.36C390.86 72.72 340.34 32 261.6 32c-60.75 0-119 23.27-161.58 65.71C58 139.5 36.25 199.93 36.25 256s20.58 113.48 61.3 155.6c43.51 44.92 105.13 68.4 168.58 68.4 57.73 0 112.45-22.62 151.45-63.66 38.34-40.4 58.17-96.3 58.17-154.9 0-24.67-2.48-39.32-2.59-39.96z" />
</Icon>
)

export const FacebookLogo = (props: IconProps) => (
<Icon viewBox="0 0 512 512" {...props}>
<title>Logo Facebook</title>
<path
d="M480 257.35c0-123.7-100.3-224-224-224s-224 100.3-224 224c0 111.8 81.9 204.47 189 221.29V322.12h-56.89v-64.77H221V208c0-56.13 33.45-87.16 84.61-87.16 24.51 0 50.15 4.38 50.15 4.38v55.13H327.5c-27.81 0-36.51 17.26-36.51 35v42h62.12l-9.92 64.77H291v156.54c107.1-16.81 189-109.48 189-221.31z"
fillRule="evenodd"
/>
</Icon>
)
81 changes: 81 additions & 0 deletions apps/builder/assets/styles/routerProgressBar.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/* Make clicks pass-through */
#nprogress {
pointer-events: none;
}

#nprogress .bar {
background: #0042da;

position: fixed;
z-index: 1031;
top: 0;
left: 0;

width: 100%;
height: 2px;
}

/* Fancy blur effect */
#nprogress .peg {
display: block;
position: absolute;
right: 0px;
width: 100px;
height: 100%;
box-shadow: 0 0 10px #0042da, 0 0 5px #0042da;
opacity: 1;

-webkit-transform: rotate(3deg) translate(0px, -4px);
-ms-transform: rotate(3deg) translate(0px, -4px);
transform: rotate(3deg) translate(0px, -4px);
}

/* Remove these to get rid of the spinner */
#nprogress .spinner {
display: block;
position: fixed;
z-index: 1031;
top: 15px;
right: 15px;
}

#nprogress .spinner-icon {
width: 18px;
height: 18px;
box-sizing: border-box;

border: solid 2px transparent;
border-top-color: #0042da;
border-left-color: #0042da;
border-radius: 50%;

-webkit-animation: nprogress-spinner 400ms linear infinite;
animation: nprogress-spinner 400ms linear infinite;
}

.nprogress-custom-parent {
overflow: hidden;
position: relative;
}

.nprogress-custom-parent #nprogress .spinner,
.nprogress-custom-parent #nprogress .bar {
position: absolute;
}

@-webkit-keyframes nprogress-spinner {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
@keyframes nprogress-spinner {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
27 changes: 27 additions & 0 deletions apps/builder/components/HOC/withUser.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { useSession } from 'next-auth/react'
import { useRouter } from 'next/router'
import { useEffect } from 'react'
import { User } from '@typebot/prisma'

export type withAuthProps = {
user?: User
}

const withAuth =
(WrappedComponent: ({ user }: withAuthProps) => JSX.Element) =>
(props: JSX.IntrinsicAttributes & withAuthProps) => {
const router = useRouter()
const { data: session, status } = useSession()

useEffect(() => {
if (!router.isReady) return
if (status === 'loading') return
if (status === 'unauthenticated') router.replace('/signin')
}, [status, router])

return (
<WrappedComponent user={session?.user as User | undefined} {...props} />
)
}

export default withAuth
33 changes: 33 additions & 0 deletions apps/builder/components/Seo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import Head from 'next/head'

export const Seo = ({
title,
currentUrl = 'https://app.typebot.io',
description = 'Create and publish conversational forms that collect 4 times more answers and feel native to your product',
imagePreviewUrl = 'https://app.typebot.io/site-preview.png',
}: {
title: string
description?: string
currentUrl?: string
imagePreviewUrl?: string
}) => (
<Head>
<title>Typebot | {title}</title>
<meta name="title" content={title} />
<meta property="og:title" content={title} />
<meta property="twitter:title" content={title} />

<meta property="twitter:url" content={currentUrl} />
<meta property="og:url" content={currentUrl} />

<meta name="description" content={description} />
<meta property="twitter:description" content={description} />
<meta property="og:description" content={description} />

<meta property="og:image" content={imagePreviewUrl} />
<meta property="twitter:image" content={imagePreviewUrl} />

<meta property="og:type" content="website" />
<meta property="twitter:card" content="summary_large_image" />
</Head>
)
26 changes: 26 additions & 0 deletions apps/builder/components/auth/AuthSwitcher.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react'
import { NextChakraLink } from '../nextChakra/NextChakraLink'
import { Text } from '@chakra-ui/react'

type Props = {
type: 'register' | 'signin'
}
export const AuthSwitcher = ({ type }: Props) => (
<>
{type === 'signin' ? (
<Text>
Don't have an account?{' '}
<NextChakraLink href="/register" color="blue.500" textDecor="underline">
Sign up for free
</NextChakraLink>
</Text>
) : (
<Text>
Already have an account?{' '}
<NextChakraLink href="/signin" color="blue.500" textDecor="underline">
Sign in
</NextChakraLink>
</Text>
)}
</>
)
Loading

0 comments on commit 5e14a94

Please sign in to comment.