Skip to content

Commit

Permalink
feat: OpenAPI definition
Browse files Browse the repository at this point in the history
  • Loading branch information
Steph0 committed Dec 11, 2024
1 parent e6a5a1a commit 782b631
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 32 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ Puis lancer les commandes suivantes :
- `npm run db:reset` -> reset de la base `API_DATABASE` contenant les requêtes et les utilisateurs
- `npm run start` -> démarrage du serveur Node

### Liste des API

Vous pouvez trouver la liste des API disponibles via la documentation OpenAPI et Swagger

- Interface : <http://localhost:3000/documentation>
- Utile pour parcourir et explorer les API
- Mode brut <http://localhost:3000/swagger.json>
- Utile pour les automatisation et les import dans vos outils de tests type Postman

### Tests autos

- `npm run test`
Expand Down
5 changes: 3 additions & 2 deletions lib/application/authentication/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Server } from '@hapi/hapi';
import Joi from 'joi';

import { SEED_PARAMETERS } from '../../common/db/seeds/seed.js';
import { checkIfUserIsBlocked } from '../security-pre-handlers.js';
import { authenticate } from './authentication.js';

Expand All @@ -13,8 +14,8 @@ const register = async function (server: Server) {
auth: false,
validate: {
payload: Joi.object({
username: Joi.string().required(),
password: Joi.string().required(),
username: Joi.string().required().example(SEED_PARAMETERS.REF_ACADEMY_USER),
password: Joi.string().required().example(SEED_PARAMETERS.REF_ACADEMY_USER_PASSWORD),
}).label('AuthenticationPayload'),
},
pre: [{ method: checkIfUserIsBlocked }],
Expand Down
7 changes: 4 additions & 3 deletions lib/application/query/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Server } from '@hapi/hapi';
import Joi from 'joi';

import { SEED_PARAMETERS } from '../../common/db/seeds/seed.js';
import { execute } from './query.js';

const register = async function (server: Server) {
Expand All @@ -11,12 +12,12 @@ const register = async function (server: Server) {
options: {
validate: {
payload: Joi.object({
queryId: Joi.string().uuid().required(),
queryId: Joi.string().uuid().required().example(SEED_PARAMETERS.REF_ACADEMY_QUERY_ID),
params: Joi.array()
.items(
Joi.object({
name: Joi.string().required(),
value: Joi.any().required(),
name: Joi.string().required().example(SEED_PARAMETERS.REF_ACADEMY_PARAM_NAME),
value: Joi.any().required().example([SEED_PARAMETERS.REF_ACADEMY_PARAM_VALUE]),
}).label('QueryParameter'),
)
.required()
Expand Down
29 changes: 18 additions & 11 deletions lib/common/db/seeds/seed.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,60 +5,67 @@ function _getNumber(numberAsString, defaultValue) {
const number = Number.parseInt(numberAsString, 10);
return Number.isNaN(number) ? defaultValue : number;
}
const seed = async function (knex) {

export const SEED_PARAMETERS = {
REF_ACADEMY_QUERY_ID: 'b1e20492-8775-47f3-926d-3729ee2b836d',
REF_ACADEMY_USER: 'dev',
REF_ACADEMY_USER_PASSWORD: 'LeMotDePasseQueL\'UtilisateurUtiliseraitDeSonPointDeVue',
REF_ACADEMY_PARAM_NAME: 'id_list',
REF_ACADEMY_PARAM_VALUE: 2,
};

export const seed = async function (knex) {
await knex('catalog_queries').insert({
name: 'Nombre d\'académies',
sql_query: 'SELECT COUNT(*) FROM data_ref_academies',
id: '1b7291d4-ac51-46d2-97f1-f5f304100a29',
created_at: new Date('2021-10-29T03:04:00Z'),
});

const refAcademiesQueryId = 'b1e20492-8775-47f3-926d-3729ee2b836d';
// const refAcademiesQueryId = 'b1e20492-8775-47f3-926d-3729ee2b836d';

await knex('catalog_queries').insert({
name: 'Académies filtrées par liste d\'id',
sql_query:
'SELECT id, nom, region, departements FROM data_ref_academies WHERE id = any({{ id_list }})',
id: refAcademiesQueryId,
id: SEED_PARAMETERS.REF_ACADEMY_QUERY_ID,
created_at: new Date('2022-05-14T13:24:00Z'),
});
await knex('catalog_query_params').insert({
id: 1,
catalog_query_id: refAcademiesQueryId,
name: 'id_list',
catalog_query_id: SEED_PARAMETERS.REF_ACADEMY_QUERY_ID,
name: SEED_PARAMETERS.REF_ACADEMY_PARAM_NAME,
type: 'int-array',
mandatory: true,
});

const hashedPassword = await bcrypt.hash(
'LeMotDePasseQueL\'UtilisateurUtiliseraitDeSonPointDeVue',
SEED_PARAMETERS.REF_ACADEMY_USER_PASSWORD,
_getNumber(env.BCRYPT_NUMBER_OF_SALT_ROUNDS, 10),
);

const userId = '456f9d47-39a7-4de6-ada2-e47662b79bf3';
await knex('users').insert({
id: userId,
username: 'dev',
username: SEED_PARAMETERS.REF_ACADEMY_USER,
label: 'Utilisateur de test',
hashed_password: hashedPassword,
created_at: new Date('2021-10-29T03:04:00Z'),
});

await knex('query_access').insert({
user_id: userId,
query_id: refAcademiesQueryId,
query_id: SEED_PARAMETERS.REF_ACADEMY_QUERY_ID,
});

await knex('query_param_access').insert({
user_id: userId,
query_param_id: 1,
value: '2',
value: `${SEED_PARAMETERS.REF_ACADEMY_PARAM_VALUE}`,
});
await knex('query_param_access').insert({
user_id: userId,
query_param_id: 1,
value: '4',
});
};

export { seed };
38 changes: 22 additions & 16 deletions lib/infrastructure/plugins/swagger.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import HapiSwagger from 'hapi-swagger';

import packageJson from '../../../package.json' with { type: 'json' };

export const swaggerPlugin = {
plugin: HapiSwagger,
options: {
info: {
title: 'API Data Documentation',
version: packageJson.version,
},
securityDefinitions: {
Bearer: {
'type': 'apiKey',
'name': 'Authorization',
'in': 'header',
'x-keyPrefix': 'Bearer ',
},
const swaggerOptions: HapiSwagger.RegisterOptions = {
OAS: 'v3.0',
uiOptions: {
url: '/openapi.json',
},
info: {
title: 'API Data Documentation',
version: packageJson.version,
},
securityDefinitions: {
bearerAuth: {
name: 'Authorization',
scheme: 'Bearer',
in: 'header',
description: 'Example: Bearer eyJ...z',
type: 'apiKey',
},
security: [{ Bearer: [] }],
},
security: [{ bearerAuth: [], jwt: [] }],
};

export const swaggerPlugin = {
plugin: HapiSwagger,
options: swaggerOptions,
};

0 comments on commit 782b631

Please sign in to comment.