269 lines
8.0 KiB
TypeScript
269 lines
8.0 KiB
TypeScript
import BaseService from "@Services/BaseService";
|
|
import { Service } from "typedi";
|
|
import { BackendVariables } from "@Common/config/variables/Variables";
|
|
import DocumentsService from "@Services/super-admin/DocumentsService/DocumentsService";
|
|
import FilesService from "../FilesService/FilesService";
|
|
|
|
export type EnrollmentResponse = {
|
|
url: string;
|
|
id: number;
|
|
api_key: string;
|
|
callback_url: string;
|
|
browser_callback_url: string;
|
|
client_reference: string;
|
|
status: string;
|
|
reason: string | null;
|
|
create_date: string;
|
|
starting_time: string | null;
|
|
finished_time: string | null;
|
|
};
|
|
|
|
type EnrollmentInfoResponse = {
|
|
status: string;
|
|
browser_callback_url: string;
|
|
browser_callback_token: string;
|
|
user_process_done_time: string | null;
|
|
routes: {
|
|
uses_biometric: boolean;
|
|
datas: {};
|
|
document_classes: string[];
|
|
constraints: string[];
|
|
id: string;
|
|
status: string;
|
|
}[];
|
|
};
|
|
|
|
type ReportInfoReponse = {
|
|
enrollment: {
|
|
callback_url: string;
|
|
browser_callback_url: string;
|
|
client_reference: string;
|
|
};
|
|
process_uuid: string;
|
|
id: number;
|
|
status: string;
|
|
process_id: number;
|
|
external_methods: {
|
|
france_connect: {
|
|
status: string;
|
|
creation_time: string;
|
|
starting_time: string;
|
|
finished_time: string;
|
|
supplier_reference: string;
|
|
results: {
|
|
france_connect_out_token: [
|
|
{
|
|
token_type: string;
|
|
scope: string;
|
|
access_token: string;
|
|
expires_in: number;
|
|
id_token: string;
|
|
expires_at: number;
|
|
},
|
|
];
|
|
france_connect_out_userinfo: [
|
|
{
|
|
sub: string;
|
|
given_name: string;
|
|
family_name: string;
|
|
birthdate: string;
|
|
gender: string;
|
|
preferred_username: string;
|
|
email: string;
|
|
},
|
|
];
|
|
};
|
|
};
|
|
};
|
|
archive_reference: string;
|
|
};
|
|
|
|
type LoginResponse = {
|
|
token: string;
|
|
};
|
|
|
|
@Service()
|
|
export default class Id360Service extends BaseService {
|
|
private id360Token: string | null = null;
|
|
private id360TokenExpiration: number | null = null;
|
|
|
|
constructor(private variables: BackendVariables, private documentsService: DocumentsService, private filesService: FilesService) {
|
|
super();
|
|
}
|
|
|
|
public async createFranceConnectEnrollment() {
|
|
const authHeader = `Token ${await this.getId360Token()}`;
|
|
const bodyArgs = {
|
|
callback_url: `${this.variables.BACK_API_HOST}/id360/customer-callback/`,
|
|
browser_callback_url: `${this.variables.APP_HOST}/id360/customer-callback/`,
|
|
callback_headers: {},
|
|
};
|
|
const res = await fetch(
|
|
`${this.variables.DOCAPOST_BASE_URL + this.variables.DOCAPOST_ROOT + this.variables.DOCAPOST_VERSION}/process/${
|
|
this.variables.DOCAPOST_CONNECT_PROCESS_ID
|
|
}/enrollment/`,
|
|
{
|
|
method: "POST",
|
|
body: JSON.stringify(bodyArgs),
|
|
headers: { "Content-Type": "application/json", Accept: "application/json", Authorization: authHeader },
|
|
},
|
|
);
|
|
|
|
const resJson = (await res.json()) as EnrollmentResponse;
|
|
return {
|
|
franceConnectUrl: `${this.variables.DOCAPOST_BASE_URL}static/process_ui/index.html#/enrollment/${resJson.api_key}`,
|
|
processId: resJson.id,
|
|
};
|
|
}
|
|
|
|
public async createEnrollment(documentUid: string) {
|
|
const authHeader = `Token ${await this.getId360Token()}`;
|
|
const bodyArgs = {
|
|
callback_url: `${this.variables.BACK_API_HOST}/id360/enrollment-callback/`,
|
|
browser_callback_url: `${
|
|
this.variables.APP_LABEL + this.variables.BACK_API_HOST + this.variables.APP_ROOT_URL
|
|
}/id360/enrollment-callback/`,
|
|
client_reference: documentUid,
|
|
callback_headers: {},
|
|
};
|
|
const res = await fetch(
|
|
`${this.variables.DOCAPOST_BASE_URL + this.variables.DOCAPOST_ROOT + this.variables.DOCAPOST_VERSION}/process/${
|
|
this.variables.DOCAPOST_DOCUMENT_PROCESS_ID
|
|
}/enrollment/`,
|
|
{
|
|
method: "POST",
|
|
body: JSON.stringify(bodyArgs),
|
|
headers: { "Content-Type": "application/json", Accept: "application/json", Authorization: authHeader },
|
|
},
|
|
);
|
|
|
|
const resJson = (await res.json()) as EnrollmentResponse;
|
|
const route = await this.getRouteId(resJson.api_key);
|
|
await this.selectRoute(resJson.api_key, route);
|
|
await this.uploadDocument(resJson.api_key, documentUid);
|
|
|
|
return await this.getReport(resJson.id);
|
|
}
|
|
|
|
public async uploadDocument(apiKey: string, documentUid: string) {
|
|
const document = await this.documentsService.getByUidWithFiles(documentUid);
|
|
if (document && document.files && document.files.length > 1) {
|
|
const IDrecto = await this.filesService.download(document.files[0]!.uid);
|
|
const IDverso = await this.filesService.download(document.files[1]!.uid);
|
|
const rectoBlobData = new Blob([new Uint8Array(Array.from(IDrecto!.buffer))], { type: "application/octet-stream" });
|
|
const versoBlobData = new Blob([new Uint8Array(Array.from(IDverso!.buffer))], { type: "application/octet-stream" });
|
|
const resRecto = await fetch(
|
|
`${
|
|
this.variables.DOCAPOST_BASE_URL + this.variables.DOCAPOST_ROOT + this.variables.DOCAPOST_VERSION
|
|
}/enrollment/flow/document/id_document_image/?total_pages=2&uploaded_page=0`,
|
|
{
|
|
method: "POST",
|
|
body: rectoBlobData,
|
|
headers: { "Content-Type": "application/octet-stream", Accept: "*/*", "x-api-key": apiKey },
|
|
},
|
|
);
|
|
|
|
const resVerso = await fetch(
|
|
`${
|
|
this.variables.DOCAPOST_BASE_URL + this.variables.DOCAPOST_ROOT + this.variables.DOCAPOST_VERSION
|
|
}/enrollment/flow/document/id_document_image/?total_pages=2&uploaded_page=1`,
|
|
{
|
|
method: "POST",
|
|
body: versoBlobData,
|
|
headers: { "Content-Type": "application/octet-stream", Accept: "*/*", "x-api-key": apiKey },
|
|
},
|
|
);
|
|
|
|
console.log(await resRecto.json(), await resVerso.json());
|
|
|
|
await this.finalizeEnrollment(apiKey);
|
|
}
|
|
}
|
|
|
|
public async getReport(enrollmentId: number) {
|
|
const authHeader = `Token ${await this.getId360Token()}`;
|
|
const res = await fetch(
|
|
`${
|
|
this.variables.DOCAPOST_BASE_URL + this.variables.DOCAPOST_ROOT + this.variables.DOCAPOST_VERSION
|
|
}/enrollment/${enrollmentId}/report/`,
|
|
{
|
|
method: "GET",
|
|
headers: { "Content-Type": "application/json", Authorization: authHeader },
|
|
},
|
|
);
|
|
|
|
return (await res.json()) as ReportInfoReponse;
|
|
}
|
|
|
|
public async getEnrollment(token: string) {
|
|
return await fetch(
|
|
`${
|
|
this.variables.DOCAPOST_BASE_URL + this.variables.DOCAPOST_ROOT + this.variables.DOCAPOST_VERSION
|
|
}/enrollment/status/${token}`,
|
|
{ method: "GET" },
|
|
);
|
|
}
|
|
|
|
public async finalizeEnrollment(apiKey: string) {
|
|
return await fetch(
|
|
`${
|
|
this.variables.DOCAPOST_BASE_URL + this.variables.DOCAPOST_ROOT + this.variables.DOCAPOST_VERSION
|
|
}/enrollment/flow/finalize_enrollment/`,
|
|
{
|
|
method: "POST",
|
|
headers: { "x-api-key": apiKey, Accept: "application/json" },
|
|
},
|
|
);
|
|
}
|
|
|
|
public async getRouteId(apiKey: string) {
|
|
const res = await fetch(
|
|
`${
|
|
this.variables.DOCAPOST_BASE_URL + this.variables.DOCAPOST_ROOT + this.variables.DOCAPOST_VERSION
|
|
}/enrollment/flow/enrollment_info/`,
|
|
{
|
|
method: "GET",
|
|
headers: { "x-api-key": apiKey, Accept: "application/json" },
|
|
},
|
|
);
|
|
const resJson = (await res.json()) as EnrollmentInfoResponse;
|
|
return resJson.routes[0]!.id;
|
|
}
|
|
|
|
public async selectRoute(apiKey: string, routeId: string) {
|
|
return await fetch(
|
|
`${
|
|
this.variables.DOCAPOST_BASE_URL + this.variables.DOCAPOST_ROOT + this.variables.DOCAPOST_VERSION
|
|
}/enrollment/flow/route/${routeId}/select`,
|
|
{
|
|
method: "POST",
|
|
headers: { "x-api-key": apiKey, Accept: "application/json" },
|
|
},
|
|
);
|
|
}
|
|
|
|
public async getId360Token() {
|
|
if (!this.id360Token || !this.id360TokenExpiration || this.id360TokenExpiration < Date.now()) {
|
|
this.id360Token = await this.login();
|
|
this.id360TokenExpiration = Date.now() + 1000 * 60 * 14; // 14 minutes
|
|
}
|
|
return this.id360Token;
|
|
}
|
|
|
|
public async login(): Promise<string> {
|
|
const bodyArgs = {
|
|
username: this.variables.DOCAPOST_APP_ID,
|
|
password: this.variables.DOCAPOST_APP_PASSWORD,
|
|
};
|
|
const res = await fetch(
|
|
`${this.variables.DOCAPOST_BASE_URL + this.variables.DOCAPOST_ROOT + this.variables.DOCAPOST_VERSION}/user/login/`,
|
|
{
|
|
method: "POST",
|
|
body: JSON.stringify(bodyArgs),
|
|
headers: { "Content-Type": "application/json", Accept: "application/json" },
|
|
},
|
|
);
|
|
return ((await res.json()) as LoginResponse).token;
|
|
}
|
|
}
|