Skip to content

Commit

Permalink
10 Create sign up flow (#55)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeroenbranje authored Jan 18, 2024
2 parents 42e134b + a8a2bc2 commit 277ec47
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 8 deletions.
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Add files here to ignore them from prettier formatting
/dist
/coverage
/.nx/cache
/.nx/cache
/apps/envited.ascs.digital/drizzle
25 changes: 24 additions & 1 deletion apps/envited.ascs.digital/app/api/user/route.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,34 @@
import { equals, isEmpty } from 'ramda'

import { db } from '../../../common/database/queries'
import { internalServerError, ok } from '../../../common/utils'
import { CredentialType } from '../../../common/types'
import { badRequest, internalServerError, ok } from '../../../common/utils'
import { extractIdFromCredential, extractIssuerIdFromCredential, extractTypeFromCredential } from '../utils'

export async function POST(request: Request) {
try {
const credential = await request.json()

const connection = await db()

const credentialId = extractIdFromCredential(credential)
const credentialIssuerId = extractIssuerIdFromCredential(credential)
const credentialType = extractTypeFromCredential(credential)

const user = await connection.getUserById(credentialId)

if (!isEmpty(user)) {
return badRequest()
}

if (equals(CredentialType.AscsUser)(credentialType as CredentialType)) {
const principal = await connection.getUserById(credentialIssuerId)

if (isEmpty(principal)) {
return badRequest()
}
}

const newUser = await connection.insertUserTx(credential)

return ok(newUser)
Expand Down
34 changes: 34 additions & 0 deletions apps/envited.ascs.digital/app/api/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { USER_CREDENTIAL } from '../../common/fixtures'
import * as SUT from './utils'

describe('api/utils', () => {
describe('extractIdFromCredential', () => {
it('should return the id from the credentialSubject', () => {
// when ... we want to get the id from the credential
// then ... we should get the id as expected
const result = SUT.extractIdFromCredential(USER_CREDENTIAL)

expect(result).toEqual('did:pkh:tz:tz1SfdVU1mor3Sgej3FmmwMH4HM1EjTzqqeE')
})
})

describe('extractIssuerIdFromCredential', () => {
it('should return the issuer id from the credential', () => {
// when ... we want to get the issuer id from the credential
// then ... we should get the id as expected
const result = SUT.extractIssuerIdFromCredential(USER_CREDENTIAL)

expect(result).toEqual('did:pkh:tz:tz1bpeJArd7apJyTUryfXH1SD6w8GL6Gwhj8')
})
})

describe('extractTypeFromCredential', () => {
it('should return the type from the credentialSubject', () => {
// when ... we want to get the type from the credential
// then ... we should get the type as expected
const result = SUT.extractTypeFromCredential(USER_CREDENTIAL)

expect(result).toEqual('AscsUser')
})
})
})
7 changes: 7 additions & 0 deletions apps/envited.ascs.digital/app/api/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { pathOr } from 'ramda'

export const extractIdFromCredential = pathOr('', ['credentialSubject', 'id'])

export const extractIssuerIdFromCredential = pathOr('', ['issuer', 'id'])

export const extractTypeFromCredential = pathOr('', ['credentialSubject', 'type'])
3 changes: 2 additions & 1 deletion apps/envited.ascs.digital/common/database/queries/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import { fromPairs, map, pipe, toPairs } from 'ramda'
import { connectDb } from '../database'
import * as schema from '../schema'
import { fetchTables } from './common'
import { insertUserTx } from './users'
import { getUserById, insertUserTx } from './users'

const queries = {
fetchTables,
getUserById,
insertUserTx,
}

Expand Down
5 changes: 4 additions & 1 deletion apps/envited.ascs.digital/common/database/queries/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import { isEmpty, prop, propOr } from 'ramda'

import * as schema from '../schema'
import { addressType, credentialType, issuer, role, user, usersToCredentialTypes, usersToRoles } from '../schema'
import { Credential, Issuer, User } from '../types'
import { Credential, DatabaseConnection, Issuer, User } from '../types'

export const getUserById = (db: DatabaseConnection) => async (id: string) =>
db.select().from(user).where(eq(user.id, id))

export const insertUsersToRolesTx =
(tx: PgTransaction<PostgresJsQueryResultHKT, typeof schema, ExtractTablesWithRelations<typeof schema>>) =>
Expand Down
1 change: 1 addition & 0 deletions apps/envited.ascs.digital/common/fixtures/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { MEMBER_CREDENTIAL } from './memberCredential'
export { USER_CREDENTIAL } from './userCredential'
export { INVALID_USER_CREDENTIAL } from './invalidUserCredential'
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const INVALID_USER_CREDENTIAL = {
url: 'https://test.de/',
},
'credentialSubject': {
id: 'did:pkh:tz:tz1SfdVU1mor3Sgej3FmmwMH4HM1EjTzqqeE',
id: 'did:pkh:tz:tz1SfdVU1mor3Sgej3FmmwMH4HM1EjTzqqeX',
type: 'AscsUser',
name: 'User',
email: 'mailto:[email protected]',
Expand Down
2 changes: 1 addition & 1 deletion apps/envited.ascs.digital/common/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { Language, Columns, Size, ColorScheme, Role } from './types'
export { Language, Columns, Size, ColorScheme, Role, CredentialType } from './types'
export type { Action, Obj } from './types'
5 changes: 5 additions & 0 deletions apps/envited.ascs.digital/common/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,8 @@ export enum Role {
principal = 'principal',
federator = 'federator',
}

export enum CredentialType {
AscsMember = 'AscsMember',
AscsUser = 'AscsUser',
}
63 changes: 61 additions & 2 deletions apps/envited.ascs.digital/modules/HeroHeader/HeroHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,64 @@

import { Button, Grid, GridRow } from '@envited-marketplace/design-system'
import { useSearchParams } from 'next/navigation'
import React, { FC } from 'react'
import React, { FC, useState } from 'react'

import { signIn } from '../../common/auth'
import { INVALID_USER_CREDENTIAL, MEMBER_CREDENTIAL, USER_CREDENTIAL } from '../../common/fixtures'
import { useTranslation } from '../../common/i18n'

export const HeroHeader: FC = () => {
const { t } = useTranslation('HeroHeader')
const searchParams = useSearchParams()
const [message, setMessage] = useState()

const addPrincipal = async () => {
try {
const result = await fetch('/api/user', {
method: 'POST',
body: JSON.stringify(MEMBER_CREDENTIAL),
})

const resultMessage = await result.json()
setMessage(resultMessage)

return result
} catch (error) {
console.log(error)
}
}

const addUser = async () => {
try {
const result = await fetch('/api/user', {
method: 'POST',
body: JSON.stringify(USER_CREDENTIAL),
})

const resultMessage = await result.json()
setMessage(resultMessage)

return result
} catch (error) {
console.log(error)
}
}

const addInvalidUser = async () => {
try {
const result = await fetch('/api/user', {
method: 'POST',
body: JSON.stringify(INVALID_USER_CREDENTIAL),
})

const resultMessage = await result.json()
setMessage(resultMessage)

return result
} catch (error) {
console.log(error)
}
}

return (
<div className="mx-auto max-w-6xl">
Expand All @@ -27,13 +77,22 @@ export const HeroHeader: FC = () => {
<Button onClick={() => signIn({ pkh: 'tz1NO_USER' })}>
<span>Test Failed Login</span>
</Button>
<Button onClick={() => addPrincipal()}>
<span>Add Principal</span>
</Button>
<Button onClick={() => addUser()}>
<span>Add User</span>
</Button>
<Button onClick={() => addInvalidUser()}>
<span>Add Invalid User</span>
</Button>
</GridRow>
</Grid>
<div className="text-center">
<div className="flex justify-center items-center"></div>
<div className="mt-10 flex items-center justify-center gap-x-6"></div>
<div className="mt-10">
<h2 className="text-lg font-bold tracking-tight text-gray-900">{t('[Heading] why')}</h2>
<h2 className="text-lg font-bold tracking-tight text-gray-900 dark:text-white">{message}</h2>
<p className="mt-2 text-md leading-8 text-gray-600">{t('[Description] why')}</p>
</div>
</div>
Expand Down

0 comments on commit 277ec47

Please sign in to comment.