-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
67 changed files
with
6,575 additions
and
325 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
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
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 |
---|---|---|
@@ -1,51 +1,90 @@ | ||
import { Controller, Get, Inject, Param, Query, Res } from '@nestjs/common'; | ||
import { | ||
CREDENTIAL_CREATOR_FACADE, | ||
ICredentialCreatorFacade | ||
} from '../../core/applications/credentials/facade/icredential.facade'; | ||
import { Response } from 'express'; | ||
import { AuthCallbackApiResponse } from './auth.callback.response.api'; | ||
import { AUTH_CONTROLLER_MAPPER, IAuthControllerMapper } from './mapper/iauth.controller.mapper'; | ||
import { AuthGetAuthUrlRequestApiRequestParam } from './auth.get-auth-url.request.api'; | ||
import { Body, Controller, Get, Inject, Post, Req, Res, UseGuards } from '@nestjs/common'; | ||
import { JustaName } from '@justaname.id/sdk'; | ||
import { ENVIRONMENT_GETTER, IEnvironmentGetter } from '../../core/applications/environment/ienvironment.getter'; | ||
import { AuthSigninApiRequest } from './requests/auth.signin.api.request'; | ||
import { Response, Request} from 'express'; | ||
import { JwtService } from '@nestjs/jwt'; | ||
import moment from 'moment'; | ||
import { JwtGuard } from '../../guards/jwt.guard'; | ||
|
||
type Siwj = { address: string, subname: string }; | ||
|
||
@Controller('auth') | ||
export class AuthController { | ||
|
||
justaname: JustaName | ||
constructor( | ||
@Inject(CREDENTIAL_CREATOR_FACADE) | ||
private readonly credentialCreatorFacade: ICredentialCreatorFacade, | ||
@Inject(ENVIRONMENT_GETTER) private readonly environmentGetter: IEnvironmentGetter, | ||
|
||
private readonly jwtService: JwtService | ||
) { | ||
this.justaname = JustaName.init({ | ||
config: { | ||
chainId: this.environmentGetter.getChainId(), | ||
domain: this.environmentGetter.getSiweDomain(), | ||
origin:this.environmentGetter.getSiweOrigin(), | ||
}, | ||
ensDomain: this.environmentGetter.getEnsDomain(), | ||
providerUrl: 'https://sepolia.infura.io/v3/' +this.environmentGetter.getInfuraProjectId() | ||
}) | ||
} | ||
|
||
@Get('nonce') | ||
async getNonce() { | ||
return this.justaname.signIn.generateNonce() | ||
} | ||
|
||
@Post('signin') | ||
async signInChallenge( | ||
@Body() body: AuthSigninApiRequest, | ||
@Res() res: Response, | ||
@Req() req: Request | ||
) { | ||
const { data: message, subname } = await this.justaname.signIn.signIn(body.message, body.signature) | ||
|
||
if (!message) { | ||
res.status(500).json({ message: 'No message returned.' }); | ||
return; | ||
} | ||
|
||
if (!message.expirationTime) { | ||
res.status(500).json({ message: 'No expirationTime returned.' }); | ||
return; | ||
} | ||
|
||
|
||
@Inject(AUTH_CONTROLLER_MAPPER) | ||
private readonly authControllerMapper: IAuthControllerMapper | ||
) {} | ||
const token = this.jwtService.sign({ subname, address: message.address }, { | ||
expiresIn: moment(message.expirationTime).diff(moment(), 'seconds') | ||
}); | ||
|
||
|
||
res.cookie('justanidtoken', token, { httpOnly: true, secure: true, sameSite: 'none' }); | ||
|
||
return res.status(200).send({ subname, address: message.address }); | ||
|
||
@Get('') | ||
async welcomeToJustaNameVerifications(): Promise<string[]> { | ||
return ['Welcome to JustaName Verifications! Please use the /auth/:authName endpoint to get started.'] | ||
} | ||
|
||
@Get(':authName') | ||
async getAuthUrl( | ||
@Param() authGetAuthUrlRequestApi: AuthGetAuthUrlRequestApiRequestParam, | ||
@UseGuards(JwtGuard) | ||
@Get('session') | ||
async getSession( | ||
@Req() req: Request & { user: Siwj }, | ||
@Res() res: Response | ||
): Promise<void> { | ||
const redirect = await this.credentialCreatorFacade.getAuthUrl(authGetAuthUrlRequestApi.authName) | ||
if(redirect.startsWith('http')) { | ||
res.redirect(redirect) | ||
return | ||
) { | ||
if (!req.user) { | ||
res.status(401).json({ message: 'You have to first sign_in' }); | ||
return; | ||
} | ||
res.send(redirect) | ||
res.setHeader('Content-Type', 'text/plain'); | ||
res.status(200).send({ subname: req.user?.subname, address: req.user?.address }); | ||
} | ||
|
||
@Get(':authName/callback') | ||
async callback( | ||
@Param() authGetAuthUrlRequestApiParam: AuthGetAuthUrlRequestApiRequestParam, | ||
@Query() authGetAuthUrlRequestApiQuery: any, | ||
): Promise<AuthCallbackApiResponse> { | ||
const verifiedEthereumEip712Signature2021 = await this.credentialCreatorFacade.callback( | ||
this.authControllerMapper.mapAuthCallbackApiRequestToCredentialCallbackRequest( | ||
authGetAuthUrlRequestApiQuery, | ||
authGetAuthUrlRequestApiParam) | ||
) | ||
return this.authControllerMapper.mapCredentialCallbackResponseToAuthCallbackApiResponse(verifiedEthereumEip712Signature2021) | ||
@UseGuards(JwtGuard) | ||
@Get('signout') | ||
async signOut( | ||
@Req() req: Request, | ||
@Res() res: Response | ||
) { | ||
res.clearCookie('justanidtoken'); | ||
res.status(200).send({ message: 'You have been signed out' }); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
apps/vc-api/src/api/auth/requests/auth.signin.api.request.ts
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,12 @@ | ||
import { IsString } from 'class-validator'; | ||
import { ApiProperty } from '@nestjs/swagger'; | ||
|
||
export class AuthSigninApiRequest { | ||
@ApiProperty() | ||
@IsString() | ||
message: string; | ||
|
||
@ApiProperty() | ||
@IsString() | ||
signature: string; | ||
} |
File renamed without changes.
115 changes: 115 additions & 0 deletions
115
apps/vc-api/src/api/credentials/credentials.controller.ts
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,115 @@ | ||
import { Controller, Get, Inject, Param, Query, Req, Res, Session, UseGuards } from '@nestjs/common'; | ||
import { | ||
CREDENTIAL_CREATOR_FACADE, | ||
ICredentialCreatorFacade | ||
} from '../../core/applications/credentials/facade/icredential.facade'; | ||
import { Response } from 'express'; | ||
import { AUTH_CONTROLLER_MAPPER, IcredentialsControllerMapper } from './mapper/icredentials.controller.mapper'; | ||
import { CredentialsGetAuthUrlRequestApiRequestParam } from './credentials.get-auth-url.request.api'; | ||
import { v4 as uuidv4 } from 'uuid'; | ||
import { filter, Subject, take } from 'rxjs'; | ||
import { SubjectData } from './isubject.data'; | ||
import { JwtGuard } from '../../guards/jwt.guard'; | ||
|
||
type Siwj = { address: string, subname: string }; | ||
|
||
@Controller('credentials') | ||
export class CredentialsController { | ||
|
||
private authSubjects: Map<string, Subject<SubjectData>> = new Map(); | ||
|
||
constructor( | ||
@Inject(CREDENTIAL_CREATOR_FACADE) | ||
private readonly credentialCreatorFacade: ICredentialCreatorFacade, | ||
|
||
@Inject(AUTH_CONTROLLER_MAPPER) | ||
private readonly authControllerMapper: IcredentialsControllerMapper | ||
) {} | ||
|
||
@Get('') | ||
async welcomeToJustaNameVerifications(): Promise<string[]> { | ||
return ['Welcome to JustaName Verifications! Please use the /auth/:authName endpoint to get started.'] | ||
} | ||
|
||
@UseGuards(JwtGuard) | ||
@Get(':authName') | ||
async getAuthUrl( | ||
@Param() authGetAuthUrlRequestApi: CredentialsGetAuthUrlRequestApiRequestParam, | ||
@Res() res: Response, | ||
@Req() req: Request & { user: Siwj } | ||
): Promise<any> { | ||
|
||
const authId = uuidv4(); | ||
const subject = new Subject<SubjectData>(); | ||
this.authSubjects.set(authId, subject); | ||
|
||
const redirectUrl = await this.credentialCreatorFacade.getAuthUrl( | ||
authGetAuthUrlRequestApi.authName, | ||
req.user?.subname, | ||
authId | ||
) | ||
|
||
|
||
res.writeHead(200, { | ||
'Content-Type': 'text/event-stream', | ||
'Cache-Control': 'no-cache', | ||
'Connection': 'keep-alive' | ||
}); | ||
|
||
res.write(`data: ${JSON.stringify({ redirectUrl })}\n\n`); | ||
|
||
subject.pipe( | ||
filter(data => data.authId === authId), | ||
take(1) | ||
).subscribe( | ||
(data) => { | ||
res.write(`data: ${JSON.stringify(data.result)}\n\n`); | ||
res.end(); | ||
this.authSubjects.delete(authId); | ||
}, | ||
(error) => { | ||
res.write(`data: ${JSON.stringify({ error: error.message })}\n\n`); | ||
res.end(); | ||
this.authSubjects.delete(authId); | ||
} | ||
); | ||
} | ||
|
||
@Get(':authName/callback') | ||
async callback( | ||
@Param() authGetAuthUrlRequestApiParam: CredentialsGetAuthUrlRequestApiRequestParam, | ||
@Query() authGetAuthUrlRequestApiQuery: any, | ||
@Res() res: Response | ||
): Promise<void> { | ||
const verifiedEthereumEip712Signature2021 = await this.credentialCreatorFacade.callback( | ||
this.authControllerMapper.mapAuthCallbackApiRequestToCredentialCallbackRequest( | ||
authGetAuthUrlRequestApiQuery, | ||
authGetAuthUrlRequestApiParam) | ||
) | ||
|
||
const { authId, dataKey, verifiableCredential} = verifiedEthereumEip712Signature2021 | ||
|
||
const subject = this.authSubjects.get(authId); | ||
subject?.next({ | ||
authId, | ||
result: { | ||
verifiableCredential, | ||
dataKey | ||
} | ||
}); | ||
|
||
|
||
res.send(` | ||
<html> | ||
<body> | ||
<script> | ||
window.close(); | ||
// In case window.close() doesn't work (e.g., in some browsers where the window wasn't opened by script) | ||
document.body.innerHTML = "Authentication successful. You can close this tab."; | ||
</script> | ||
</body> | ||
</html> | ||
`); | ||
|
||
} | ||
} |
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
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,9 @@ | ||
import { VerifiedEthereumEip712Signature2021 } from '../../core/domain/entities/eip712'; | ||
|
||
export interface SubjectData { | ||
authId: string; | ||
result: { | ||
verifiableCredential: VerifiedEthereumEip712Signature2021; | ||
dataKey: string; | ||
}; | ||
} |
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
10 changes: 5 additions & 5 deletions
10
...pi/auth/mapper/iauth.controller.mapper.ts → .../mapper/icredentials.controller.mapper.ts
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 |
---|---|---|
@@ -1,17 +1,17 @@ | ||
import { AuthCallbackApiResponse } from '../auth.callback.response.api'; | ||
import { AuthCallbackApiResponse } from '../credentials.callback.response.api'; | ||
import { CredentialCallbackResponse } from '../../../core/applications/credentials/facade/credential.callback.response'; | ||
import { AuthGetAuthUrlApiRequestQuery, AuthGetAuthUrlRequestApiRequestParam } from '../auth.get-auth-url.request.api'; | ||
import { CredentialsGetAuthUrlApiRequestQuery, CredentialsGetAuthUrlRequestApiRequestParam } from '../credentials.get-auth-url.request.api'; | ||
import { CredentialCallbackRequest } from '../../../core/applications/credentials/facade/credential.callback.request'; | ||
|
||
export const AUTH_CONTROLLER_MAPPER = 'AUTH_CONTROLLER_MAPPER'; | ||
|
||
export interface IAuthControllerMapper { | ||
export interface IcredentialsControllerMapper { | ||
mapCredentialCallbackResponseToAuthCallbackApiResponse( | ||
credentialCallbackResponse: CredentialCallbackResponse, | ||
): AuthCallbackApiResponse; | ||
|
||
mapAuthCallbackApiRequestToCredentialCallbackRequest( | ||
authCallbackApiRequestQuery: AuthGetAuthUrlApiRequestQuery, | ||
authCallbackApiRequestParams: AuthGetAuthUrlRequestApiRequestParam | ||
authCallbackApiRequestQuery: CredentialsGetAuthUrlApiRequestQuery, | ||
authCallbackApiRequestParams: CredentialsGetAuthUrlRequestApiRequestParam | ||
): CredentialCallbackRequest; | ||
} |
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
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
Oops, something went wrong.