Commit 6806919d authored by Hidde-Jan Jongsma's avatar Hidde-Jan Jongsma

Add creating requests from jwt tokens

parent ddd5d1ca
......@@ -4,6 +4,7 @@ import {
Column,
OneToOne,
OneToMany,
Generated,
} from 'typeorm';
import { randomBytes } from 'crypto';
import { JolocomWallet } from '../connectors/jolocom/jolocom-wallet.entity';
......@@ -23,6 +24,10 @@ export class Organization {
@Column()
sharedSecret: string;
@Column()
@Generated('uuid')
uuid: string;
@OneToOne(
() => JolocomWallet,
wallet => wallet.organization,
......
......@@ -10,5 +10,6 @@ import { ConnectorsModule } from 'src/connectors/connectors.module';
imports: [TypeOrmModule.forFeature([Organization]), ConnectorsModule],
controllers: [OrganizationsController],
providers: [OrganizationsService],
exports: [OrganizationsService],
})
export class OrganizationsModule {}
......@@ -22,8 +22,9 @@ export class OrganizationsService {
}
async findByIdentifier(uuid: string) {
const results = await this.organizationsRepository.find({ take: 1 });
return results[0];
return this.organizationsRepository.findOne({
uuid,
});
}
async createFromName(name: string) {
......@@ -32,7 +33,10 @@ export class OrganizationsService {
organization.name = name;
organization.sharedSecret = Organization.randomSecret();
await this.organizationsRepository.save(organization);
// TODO: Move to queue if needed.
await this.connectorsService.registerOrganization(organization);
this.logger.log(`Created organization (id: ${organization.id})`);
return organization;
}
......
......@@ -43,8 +43,14 @@ export class CredentialIssueRequest implements CredentialRequest {
)
requestor: Organization;
static requestType: 'credential-issue-request';
get requestId() {
return `credential-issue-request:${this.uuid}`;
return `${CredentialIssueRequest.requestType}:${this.uuid}`;
}
get iss() {
return this.requestor?.uuid;
}
get issuer() {
......
......@@ -2,6 +2,7 @@ import { Organization } from '../organizations/organization.entity';
export interface CredentialRequest {
requestId: string;
iss: string;
type: string;
callbackUrl: string;
requestor: Organization;
......
......@@ -35,8 +35,14 @@ export class CredentialVerifyRequest implements CredentialRequest {
)
requestor: Organization;
static requestType: 'credential-verify-request';
get requestId() {
return `credential-verify-request:${this.uuid}`;
return `${CredentialVerifyRequest.requestType}:${this.uuid}`;
}
get iss() {
return this.requestor?.uuid;
}
get verifier() {
......
import { Module } from '@nestjs/common';
import { RequestsService } from './requests.service';
import { OrganizationsModule } from '../organizations/organizations.module';
import { TypeOrmModule } from '@nestjs/typeorm';
import { CredentialIssueRequest } from './credential-issue-request.entity';
import { CredentialVerifyRequest } from './credential-verify-request.entity';
@Module({
imports: [OrganizationsModule],
imports: [
TypeOrmModule.forFeature([CredentialIssueRequest, CredentialVerifyRequest]),
OrganizationsModule,
],
providers: [RequestsService],
exports: [RequestsService],
})
......
......@@ -11,6 +11,8 @@ import {
CredentialIssueRequest,
CredentialIssueRequestData,
} from './credential-issue-request.entity';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
export class InvalidRequestJWT extends Error {}
......@@ -18,7 +20,59 @@ const JWT_MAX_AGE = '300s';
@Injectable()
export class RequestsService {
constructor(private organizationsService: OrganizationsService) {}
constructor(
private organizationsService: OrganizationsService,
@InjectRepository(CredentialIssueRequest)
private issueRequestRepository: Repository<CredentialIssueRequest>,
@InjectRepository(CredentialVerifyRequest)
private verifyRequestRepository: Repository<CredentialVerifyRequest>,
) {}
async findVerifyRequestByIdentifier(uuid: string) {
return this.verifyRequestRepository.findOne({ uuid });
}
async findIssueRequestByIdentifier(uuid: string) {
return this.issueRequestRepository.findOne({ uuid });
}
async findVerifyRequestByRequestId(requestId: string) {
const [type, uuid] = requestId.split(':');
if (type !== CredentialVerifyRequest.requestType || !uuid) {
return null;
}
return this.findVerifyRequestByIdentifier(uuid);
}
async findIssueRequestByRequestId(requestId: string) {
const [type, uuid] = requestId.split(':');
if (type !== CredentialIssueRequest.requestType || !uuid) {
return null;
}
return this.findIssueRequestByIdentifier(uuid);
}
async findRequestByRequestId(requestId: string) {
const [type, uuid] = requestId.split(':');
if (!type || !uuid) {
return null;
}
if (type === CredentialVerifyRequest.requestType) {
return this.findVerifyRequestByIdentifier(uuid);
}
if (type === CredentialIssueRequest.requestType) {
return this.findIssueRequestByIdentifier(uuid);
}
return null;
}
async decodeVerifyRequestToken(jwt: string) {
const { request, requestor } = await this.decodeAndVerifyJwt<
......@@ -31,8 +85,7 @@ export class RequestsService {
verifyRequest.type = request.type;
verifyRequest.callbackUrl = request.callbackUrl;
// TODO: Save to db
await this.verifyRequestRepository.save(verifyRequest);
return verifyRequest;
}
......@@ -48,8 +101,7 @@ export class RequestsService {
issueRequest.callbackUrl = request.callbackUrl;
issueRequest.data = request.data;
// TODO: Save to db
await this.issueRequestRepository.save(issueRequest);
return issueRequest;
}
......@@ -82,6 +134,10 @@ export class RequestsService {
throw new Error(`String returned '${request}'. Expecting json object`);
}
// This is an unsafe casting that creates a runtime exception if the
// casting fails. A more robust solution would be to use the
// class-transformer and class-validator libraries to make sure the object
// is valid.
return { request: (request as unknown) as T, requestor };
} catch (e) {
throw new InvalidRequestJWT('Could not decode request JWT');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment