Skip to content
This repository has been archived by the owner on Oct 14, 2023. It is now read-only.

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
lukesthl committed Oct 1, 2023
0 parents commit e208478
Show file tree
Hide file tree
Showing 47 changed files with 8,904 additions and 0 deletions.
15 changes: 15 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
SUPERTOKENS_CONNECTION_URI=your-supertokens-connection-uri
SUPERTOKENS_API_KEY=your-supertokens-api-key
API_DOMAIN=http://localhost:4000
PORT=4000
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
APPLE_CLIENT_ID=your-apple-client-id
APPLE_PRIVATE_KEY=your-apple-private-key
APPLE_TEAM_ID=your-apple-team-id
APPLE_KEY_ID=your-apple-key-id
ACCOUNT_JWT_SECRET=custom-jwt-secret
RESEND_API_KEY=your-resend-api-key
EMAIL_FROM=your-email
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
25 changes: 25 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
tsconfigRootDir: __dirname,
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
root: true,
env: {
node: true,
jest: true,
},
ignorePatterns: ['.eslintrc.js'],
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
},
};
54 changes: 54 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Lint

on:
push:
branches:
- main
pull_request:
branches:
- main
# Allow this workflow to be triggered manually (ex: in GitHub UI)
workflow_dispatch:

permissions:
checks: write
contents: write

jobs:
lint:
name: Run Lint
runs-on: ubuntu-latest
steps:
# Checks out the repository and enables the use of commands made available in the project ie npm run
- name: Checkout Git repository
uses: actions/checkout@v3
# Configure npm
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 20

- uses: pnpm/action-setup@v2
name: Install pnpm
with:
version: 8
run_install: false

- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install

- name: Run linters
run: 'pnpm run lint && pnpm run format'
112 changes: 112 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
name: Deploy Production
# This workflow builds Docker images for each app, then pushes the images to GitHub Container Registry
# After all images are built and pushed successfully, it deploys each image to Caprover (staging)

on:
workflow_run:
workflows: ['Lint']
branches: [main]
types:
- completed
# Allow this workflow to be triggered manually (ex: in GitHub UI)
workflow_dispatch:

jobs:
build:
name: Build
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
environment: production
permissions:
contents: read
packages: write
outputs:
# output the image tag that was built and pushed so we can deploy this image tag in the deploy job
image-tag: ${{ steps.set-image-tag.outputs.image-tag }}
steps:
#
# ------------------ Setup -----------------------
#

# checkout GitHub repository
- name: Checkout
uses: actions/checkout@v4

# If merge event triggered this, get the name of the branch
- name: Get branch name (merge)
if: github.event_name != 'pull_request'
shell: bash
run: echo "BRANCH_NAME=$(echo ${GITHUB_REF#refs/heads/} | tr / -)" >> $GITHUB_ENV

# If PR create event triggered this, get the name of the branch
- name: Get branch name (pull request)
if: github.event_name == 'pull_request'
shell: bash
run: echo "BRANCH_NAME=$(echo ${GITHUB_HEAD_REF} | tr / -)" >> $GITHUB_ENV

# install QEMU, a utility for building docker images
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
# This creates docker tags
# https://github.com/docker/build-push-action/blob/master/docs/advanced/tags-labels.md
- name: Docker meta
id: docker-meta
uses: docker/metadata-action@v4
with:
# list of Docker images to use as base name for tags
images: |
ghcr.io/${{ github.repository }}
# generate Docker tags based on the following events/attributes
tags: |
type=sha,prefix=${{ env.BRANCH_NAME }}-,priority=1000
type=semver,priority=900,pattern={{version}},prefix=staging-
- name: 'Build and push image'
uses: docker/build-push-action@v3
with:
file: 'Dockerfile'
context: '.'
platforms: linux/amd64
push: true
tags: ${{ steps.docker-meta.outputs.tags }}
labels: ${{ steps.docker-meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- id: set-image-tag
run: echo "image-tag=${{ fromJson(steps.docker-meta.outputs.json).tags[0] }}" >> $GITHUB_OUTPUT
deploy:
name: Deploy Production
runs-on: ubuntu-latest
needs: [build]
environment: production
concurrency: production

env:
CAPROVER_URL: ${{ secrets.CAPROVER_URL }}
CAPROVER_APP_TOKEN: ${{ secrets.CAPROVER_APP_TOKEN }}
strategy:
matrix:
include:
- app: ${{ github.event.repository.name }} # name of the app in Caprover
token-key: env.CAPROVER_APP_TOKEN # key used to get CAPROVER_APP_TOKEN from env
image: ${{ needs.build.outputs.image-tag }} # image to deploy
steps:
# Install Caprover CLI, which we use to deploy images to Caprover
- name: 'Install caprover-cli'
run: npm install -g caprover

# Deploy each app by iterating over matrix values
- name: 'Deploy ${{ matrix.app }}'
env:
APP_NAME: ${{ matrix.app }}
APP_URL: ${{ env.CAPROVER_URL }}
CAPROVER_APP_TOKEN: ${{ env.CAPROVER_APP_TOKEN }}
IMAGE_NAME: ${{ matrix.image }}
run: 'caprover deploy --caproverUrl=$APP_URL --appToken=$CAPROVER_APP_TOKEN --imageName=$IMAGE_NAME --appName=$APP_NAME'
38 changes: 38 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# compiled output
/dist
/node_modules

# Logs
logs
*.log
npm-debug.log*
pnpm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# OS
.DS_Store

# Tests
/coverage
/.nyc_output

# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace

# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

.env
env
4 changes: 4 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"singleQuote": true,
"trailingComma": "all"
}
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"typescript.tsdk": "node_modules/typescript/lib"
}
19 changes: 19 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM node:20-slim AS base
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
COPY . /app
WORKDIR /app

FROM base AS prod-deps
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile

FROM base AS build
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
RUN pnpm run build

FROM base
COPY --from=prod-deps /app/node_modules /app/node_modules
COPY --from=build /app/dist /app/dist
EXPOSE 3000
CMD [ "pnpm", "start:prod" ]
87 changes: 87 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<p align="center" style="display:flex; justify-content:center; align-items:center">
<img src="https://nestjs.com/img/logo-small.svg" height="56"><img src="./docs/supertokens-logo.png" height="64">
</p>

# Nestjs Template for [expo-supertokens](https://github.com/lukesthl/expo-supertokens) with Supertokens Authentication

This project template provides the backend for developing a React Native application with Expo and Supertokens to authenticate. It is built with [Nestjs](https://nestjs.com/) and [Supertokens](https://supertokens.io/).

## Key Features:

- [**Sign in with Apple, GitHub, Google, or Email and Password**](https://supertokens.com/docs/thirdpartyemailpassword/introduction): The authentication flow supports multiple sign-in options using Supertokens.
- [**Role Management**](https://supertokens.com/docs/thirdpartyemailpassword/introduction): You can manage user roles and permissions within your application using Supertokens.
- [**Change Password, Verify E-Mail and Delete Account Views**](https://docs.expo.dev/guides/deep-linking/): Connect your app to a website by adding support for deep linking.
- [**Handlebars E-Mail Templates**](https://docs.expo.dev/routing/introduction/): It utilizes Expo Router, a versatile routing solution for navigating between screens in your application.

## Getting Started

To use this template, follow the steps below:

1. Clone the repository
`git clone https://github.com/lukesthl/nestjs-supertokens`
2. Install dependencies
`pnpm install`
3. Configure the Supertokens Backend with your authentication providers (Apple, GitHub, Google, etc.)
4. Setup environment variables:

- `cp .env.example .env`
- Update the necessary environment variables for Supertokens configuration. For example:

```
SUPERTOKENS_CONNECTION_URI=your-supertokens-connection-uri
SUPERTOKENS_API_KEY=your-supertokens-api-key
ACCOUNT_JWT_SECRET=custom-jwt-secret # jwt secret for delete account token
RESEND_API_KEY=your-resend-api-key # Get this from https://resend.com/api-keys
[email protected]
```

5. Start the app
`pnpm run start:dev`

### Configuring the Authentication Providers

To configure Supertokens with your authentication providers, follow the documentation provided by Supertokens. This typically involves registering your app with each provider and obtaining API keys or tokens required for authentication.

### Apple

Generate a private key for your Apple App ID. You can find more information about this [here](https://developer.apple.com/help/account/configure-app-capabilities/configure-sign-in-with-apple-for-the-web/).

```
APPLE_CLIENT_ID=your-apple-client-id
APPLE_PRIVATE_KEY=your-apple-private-key
APPLE_TEAM_ID=your-apple-team-id
APPLE_KEY_ID=your-apple-key-id
```

### GitHub

Register your app with GitHub and obtain a client ID and secret. You can find more information about this [here](https://docs.github.com/en/developers/apps/creating-an-oauth-app).

```
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
```

### Google

Register your app with Google and obtain a client ID and secret. You can find more information about this [here](https://developers.google.com/identity/protocols/oauth2).

```
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
```

### Customizing the Template

Customizing the E-Mails in the template is easy. Simply edit the Handlebars templates in the `./emails/auth` folder. For Updating the HTML views, edit the files in the `./views/auth` folder.

## Setup Apple App site association (ASA)

For iOS, you need to setup the Apple App site association (ASA) file. This is required for deep linking to work on iOS. The File can be found in the `./public/.well-known` folder. You can find more information about this [here](https://docs.expo.dev/guides/deep-linking/).

### Known Issues

## Learn more

- [Supertokens Documentation](https://supertokens.io/docs/)
- [Nestjs Documentation](https://docs.nestjs.com/)
Binary file added docs/supertokens-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit e208478

Please sign in to comment.