Skip to content

Commit

Permalink
feat(envited.ascs.digital): add next-auth (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
royscheeren authored Jan 11, 2024
2 parents 2c06fed + 71b0f55 commit 1a8725f
Show file tree
Hide file tree
Showing 24 changed files with 243 additions and 84 deletions.
2 changes: 2 additions & 0 deletions apps/envited.ascs.digital/.env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
ENV='development'
REGION='eu-central-1'
NEXTAUTH_URL='http://localhost:4200'
NEXTAUTH_SECRET='my-secret'

# .env.development only
POSTGRES_HOST='localhost'
Expand Down
62 changes: 62 additions & 0 deletions apps/envited.ascs.digital/app/api/auth/[...nextauth]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import NextAuth from 'next-auth'
import type { NextAuthOptions } from 'next-auth'
import CredentialsProvider from 'next-auth/providers/credentials'

export const authOptions: NextAuthOptions = {
providers: [
CredentialsProvider({
// The name to display on the sign in form (e.g. 'Sign in with...')
name: 'Sign in with Your Credentials',
// The credentials is used to generate a suitable form on the sign in page.
// You can specify whatever fields you are expecting to be submitted.
// e.g. domain, username, password, 2FA token, etc.
// You can pass any HTML attribute to the <input> tag through the object.
credentials: {
pkh: { label: 'Address', type: 'text', placeholder: 'tz...' },
},
async authorize(credentials) {
if (!credentials) {
return {
id: '',
pkh: '',
memberId: '',
role: '',
}
}
const { pkh } = credentials

return {
id: '',
pkh,
memberId: '',
role: '',
}
},
}),
],
session: {
strategy: 'jwt',
},
callbacks: {
async jwt({ token, user }) {
if (user) {
token.user = user
}

return token
},
async session({ session, token }: { session: any; token: any }) {
session.user.pkh = token.user.pkh
session.user.role = token.user.role
session.user.memberId = token.user.memberId
session.user.id = token.sub
session.user.email = undefined
session.user.image = undefined
return session
},
},
}

const handler = NextAuth(authOptions)

export { handler as GET, handler as POST }
2 changes: 1 addition & 1 deletion apps/envited.ascs.digital/app/api/hello/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ok } from '../../../common/utils'
import { db } from '../../../common/database/queries'
import { ok } from '../../../common/utils'

export async function GET(request: Request) {
try {
Expand Down
14 changes: 14 additions & 0 deletions apps/envited.ascs.digital/app/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { getServerSession } from '../../common/session'
import { Header } from '../../modules/Header'

export default async function Index() {
const session = await getServerSession()
return (
<>
<Header />
<main>
<div className="mx-auto max-w-6xl">{session ? JSON.stringify(session) : 'No session'}</div>
</main>
</>
)
}
16 changes: 10 additions & 6 deletions apps/envited.ascs.digital/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@ import { Providers } from '../modules/Theme/Providers'
import './global.css'

export const metadata = {
title: 'Welcome to marketplace',
description: 'Generated by create-nx-workspace',
title: 'Envited Marketplace',
description: '',
}

export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<Providers>
<body className="bg-white dark:bg-gray-800">{children}</body>
</Providers>
<html lang="en" suppressHydrationWarning>
<head>
<title>{metadata.title}</title>
<meta name="description" content={metadata.description} />
</head>
<body className="bg-white dark:bg-gray-800">
<Providers>{children}</Providers>
</body>
</html>
)
}
4 changes: 1 addition & 3 deletions apps/envited.ascs.digital/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
'use client'

import { ExampleTable } from '../modules/ExampleTable'
import { Header } from '../modules/Header'
import { HeroHeader } from '../modules/HeroHeader'

export default function Index() {
export default async function Index() {
return (
<>
<Header />
Expand Down
7 changes: 3 additions & 4 deletions apps/envited.ascs.digital/common/database/migrate.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { RDSDataClient } from '@aws-sdk/client-rds-data'
import { fromIni } from '@aws-sdk/credential-providers'
import { drizzle as RDSDrizzle } from 'drizzle-orm/aws-data-api/pg'
import { migrate as AWSDataApiMigrate } from 'drizzle-orm/aws-data-api/pg/migrator'
import { PostgresJsDatabase } from 'drizzle-orm/postgres-js'
import { migrate as PGMigrate } from 'drizzle-orm/postgres-js/migrator'
import { migrate as AWSDataApiMigrate } from 'drizzle-orm/aws-data-api/pg/migrator'
import { drizzle as RDSDrizzle } from 'drizzle-orm/aws-data-api/pg'

import { connectDb } from './database'
import * as schema from './schema'

const runMigration = async () => {

try {
if (process.env.ENV === 'development') {
const db = await connectDb()
Expand All @@ -21,7 +20,7 @@ const runMigration = async () => {
credentials: fromIni({ profile: process.env.AWS_PROFILE || '' }),
region: 'eu-central-1',
})

const db = RDSDrizzle(rdsClient, {
database: process.env.RDS_DB_NAME || '',
secretArn: process.env.RDS_SECRET_ARN || '',
Expand Down
7 changes: 3 additions & 4 deletions apps/envited.ascs.digital/common/database/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ import { connectDb } from './database'
import { role } from './schema'
import * as schema from './schema'

const insertRoles = (connection: any) => async (roles: any[]) =>
connection.insert(role).values(roles).execute()
const insertRoles = (connection: any) => async (roles: any[]) => connection.insert(role).values(roles).execute()

const seed = async () => {
try {
// Insert seeding requirements here
let connection = null

if (process.env.ENV === 'development') {
connection = await connectDb()
return
Expand All @@ -23,7 +22,7 @@ const seed = async () => {
credentials: fromIni({ profile: process.env.AWS_PROFILE || '' }),
region: 'eu-central-1',
})

connection = RDSDrizzle(rdsClient, {
database: process.env.RDS_DB_NAME || '',
secretArn: process.env.RDS_SECRET_ARN || '',
Expand Down
1 change: 1 addition & 0 deletions apps/envited.ascs.digital/common/session/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { getServerSession } from './session'
17 changes: 17 additions & 0 deletions apps/envited.ascs.digital/common/session/session.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { _getServerSession } from './session'

describe('common/session', () => {
describe('getServerSession', () => {
it('should should fetch a server session with the correct parameters', async () => {
// when ... we want to get the current session server side
// then ... it should call the getServerSession function with the correct parameters
const authOptions = 'AUTH_OPTIONS' as any
const NAGetServerSession = jest.fn().mockResolvedValue('SESSION')

const session = await _getServerSession(NAGetServerSession)(authOptions)()

expect(NAGetServerSession).toHaveBeenCalledWith(authOptions)
expect(session).toEqual('SESSION')
})
})
})
8 changes: 8 additions & 0 deletions apps/envited.ascs.digital/common/session/session.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { getServerSession as NAGetServerSession, NextAuthOptions } from 'next-auth'

import { authOptions } from '../../app/api/auth/[...nextauth]/route'

export const _getServerSession = (NAGetServerSession: any) => (authOptions: NextAuthOptions) => () =>
NAGetServerSession(authOptions)

export const getServerSession = _getServerSession(NAGetServerSession)(authOptions)
9 changes: 8 additions & 1 deletion apps/envited.ascs.digital/common/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,15 @@ export type Action<T> = {
data?: Obj
}

export type Role = {
export interface IRole {
id: string
name: string
description: string
}

export enum Role {
admin = 'admin',
user = 'user',
principal = 'principal',
federator = 'federator',
}
9 changes: 4 additions & 5 deletions apps/envited.ascs.digital/common/utils/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
/**
* @jest-environment node
*/

import { RESPONSES } from '../constants';
import { RESPONSES } from '../constants'
import * as SUT from './utils'

describe('common/utils', () => {
const mockFetch = Promise.resolve({ json: () => Promise.resolve('') });
global.fetch = jest.fn().mockImplementation(() => mockFetch);
const mockFetch = Promise.resolve({ json: () => Promise.resolve('') })
global.fetch = jest.fn().mockImplementation(() => mockFetch)

describe('ok', () => {
it.each([
['Message', 'Message'],
Expand Down
15 changes: 11 additions & 4 deletions apps/envited.ascs.digital/common/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@ import { RESPONSES } from '../constants'

export const ok = (data: any) => Response.json(data)

export const badRequest = () => Response.json(null, { status: RESPONSES.badRequest.status, statusText: RESPONSES.badRequest.statusText })
export const badRequest = () =>
Response.json(null, { status: RESPONSES.badRequest.status, statusText: RESPONSES.badRequest.statusText })

export const internalServerError = () => Response.json(null, { status: RESPONSES.internalServerError.status, statusText: RESPONSES.internalServerError.statusText })
export const internalServerError = () =>
Response.json(null, {
status: RESPONSES.internalServerError.status,
statusText: RESPONSES.internalServerError.statusText,
})

export const notFound = () => Response.json(null, { status: RESPONSES.notFound.status, statusText: RESPONSES.notFound.statusText})
export const notFound = () =>
Response.json(null, { status: RESPONSES.notFound.status, statusText: RESPONSES.notFound.statusText })

export const noContent = () => new Response(null, { status: RESPONSES.noContent.status, statusText: RESPONSES.noContent.statusText })
export const noContent = () =>
new Response(null, { status: RESPONSES.noContent.status, statusText: RESPONSES.noContent.statusText })
Loading

0 comments on commit 1a8725f

Please sign in to comment.