Giter Site home page Giter Site logo

global-wellness-retreat's Introduction

Global Wellness Retreat

Project setup

npm i
npm run start

The API is then available at http://localhost:3000

Tests

Run unit tests :

npm run test

Run end-to-end tests :

npm run test:e2e

Authentication

Generate a new API key with the /auth/new-key endpoint. See details in the Endpoints section below.

To call authenticated endpoints, you must include the 2 following headers to your request:

X-GWR-Key: <your private API key>
X-GWR-Id: <the associated partner id>

Endpoints

Generate a new API key

Note

This is a helper endpoint. It was not designed as an actual way to generate a new key for a partner in a production scenario. That is why it does not require any authentication, does not validate incoming data, and is not covered by tests. See Security > Improvements for more details on what the production implementation should be.

Method Route
POST /auth/new-key
Parameter Description
partnerId A string to identify the partner account associated with the newly generated key.

Request body example (JSON)

{
  "partnerId": "test-id"
}

Response body example

lOQFlz/7k21Aph+dtqWtXKlKap+UfXW4a5m0JoThd1JisFVQWgv0BPFpFmF5GJoG

โš ๏ธ Save this key as there is no way to see it again.

Transmit client data

Note

This is the main endpoint of the project receiving client data from GWR partners

Method Route
POST /booking
Parameter Description
email Client email. Must be a valid email address
language Client language. Must be a valid locale
countryOfOrigin Client origin. Must be a valid ISO-3166-1 2 letters country code
countryOfDestination Client destination. Must be a valid ISO-3166-1 2 letters country code
travelDateStart Travel start date. Must be a valid ISO-8601 date
travelDateEnd Travel end date. Must be a valid ISO-8601 date

Request body example (JSON)

{
  "email": "[email protected]",
  "language": "fr",
  "countryOfOrigin": "us",
  "countryOfDestination": "nz",
  "travelDateStart": "2023-12-22",
  "travelDateEnd": "2024-01-22"
}

Technical choices and possible improvements

Security

Current implementation

To authenticate, GWR partners must use a secret API key on every request. The advantages of this solution are:

  • it is the simplest option to implement on the client side
  • several API keys can be associated with the same partner. This is useful to grant different authorization scopes, and to rotate keys without down time.
  • the keys can be easily revoked

The main drawback is that it can put a lot of pressure on the database and add latency if the traffic is important as a query is added for each request.

The scenario does not imply particularly high traffic, so this solution seems acceptable. Moreover, the latency can be minimized with the following improvements.

Improvements

To reduce the load on the database and the latency, we could :

  • cache key hashes in memory, as close to the client as possible to reduce the number of calls to the database
  • add a checksum at the of the key (eg. <private-key>_<checksum>) to reject malformed keys without the need for a database query

Another improvement would be to combine the id and key in a single token. This would make implementation even easier for partners. We need to keep both parts distinguishable though, as the keys are hashed with a salt. Without an id, checking the validity of a key would imply going through the whole table of key hashes one by one which is not acceptable is terms of latency.

Lastly, this implementation only focuses on the requests authentication, not on API keys management. In a production scenario, we would have partner accounts associated to a randomly generated id, expiration dates on keys, etc.

Alternate implementation

Another implementation I considered was to have a dedicated Auth endpoint to generate short-lived bearer tokens used to authenticate subsequent requests.

sequenceDiagram
    Client->>+API: POST /auth<br />X-GWR-Id: <secret-key>
    API->>DB: Find secret key
    DB->>API: Found
    API->>-Client: HTTP 200 OK<br />{ token : afe12...tz }
    loop For 5 min
    Client->>+API: POST /booking<br />Authorization: Bearer afe12...tz
    API->>API: Validate token
    API->>-Client: HTTP 201 Created
    end
Loading

This implementation would greatly reduce the load of the database in the case of a high frequency of request from partners (several requests in the time-to-live of a token).

The main drawbacks of this implementation are that :

  • it is a more complicated flow for partners to implement
  • it is more difficult to quickly revoke the tokens

I considered we were in a low frequency scenario, hence I favored the first solution.

Database

The data we need to persist is well structured and there is no other specific constraint so a relational database is the best choice in my opinion.

To simplify the setup of the project, I chose SQLite which requires virtually no setup and is very light. For a real production project with no specific constraint, the first choice would have certainly been a system with more features, like PostgreSQL.

Schema

The /booking endpoint does little more than validating the format of the parameters. It would make sense to add more business logic validation.

For example, the language parameter must be any locale. In real life, there would probably be a few supported languages only.

global-wellness-retreat's People

Contributors

victma avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.