Refactor API key validation logic

Added API page documentation
This commit is contained in:
newtbot 2024-01-22 03:23:48 +08:00
parent 3ffcfb4e77
commit 3c8dd68473
2 changed files with 398 additions and 185 deletions

View File

@ -5,156 +5,363 @@
https://github.com/ticlekiwi/API-Documentation-HTML-Template https://github.com/ticlekiwi/API-Documentation-HTML-Template
!--> !-->
<%- include('top') %> <%- include('top') %>
<body class="one-content-column-version"> <body class="one-content-column-version">
<div class="left-menu"> <div class="left-menu">
<div class="content-logo"> <div class="content-logo">
<div class="logo"> <div class="logo">
<img alt="platform by Emily van den Heever from the Noun Project" title="platform by Emily van den Heever from the Noun Project" src="images/apilogo.png" height="32" /> <img alt="platform by Emily van den Heever from the Noun Project"
<span>API Documentation</span> title="platform by Emily van den Heever from the Noun Project" src="images/apilogo.png"
</div> height="32" />
<button class="burger-menu-icon" id="button-menu-mobile"> <span>API Documentation</span>
<svg width="34" height="34" viewBox="0 0 100 100"><path class="line line1" d="M 20,29.000046 H 80.000231 C 80.000231,29.000046 94.498839,28.817352 94.532987,66.711331 94.543142,77.980673 90.966081,81.670246 85.259173,81.668997 79.552261,81.667751 75.000211,74.999942 75.000211,74.999942 L 25.000021,25.000058"></path><path class="line line2" d="M 20,50 H 80"></path><path class="line line3" d="M 20,70.999954 H 80.000231 C 80.000231,70.999954 94.498839,71.182648 94.532987,33.288669 94.543142,22.019327 90.966081,18.329754 85.259173,18.331003 79.552261,18.332249 75.000211,25.000058 75.000211,25.000058 L 25.000021,74.999942"></path></svg> </div>
</button> <button class="burger-menu-icon" id="button-menu-mobile">
</div> <svg width="34" height="34" viewBox="0 0 100 100">
<div class="mobile-menu-closer"></div> <path class="line line1"
<div class="content-menu"> d="M 20,29.000046 H 80.000231 C 80.000231,29.000046 94.498839,28.817352 94.532987,66.711331 94.543142,77.980673 90.966081,81.670246 85.259173,81.668997 79.552261,81.667751 75.000211,74.999942 75.000211,74.999942 L 25.000021,25.000058">
<div class="content-infos"> </path>
<div class="info"><b>Version:</b> 1.0.5</div> <path class="line line2" d="M 20,50 H 80"></path>
<div class="info"><b>Last Updated:</b> 15th Sep, 2021</div> <path class="line line3"
</div> d="M 20,70.999954 H 80.000231 C 80.000231,70.999954 94.498839,71.182648 94.532987,33.288669 94.543142,22.019327 90.966081,18.329754 85.259173,18.331003 79.552261,18.332249 75.000211,25.000058 75.000211,25.000058 L 25.000021,74.999942">
<ul> </path>
<li class="scroll-to-link active" data-target="content-get-started"> </svg>
<a>GET STARTED</a> </button>
</li> </div>
<li class="scroll-to-link" data-target="content-get-characters"> <div class="mobile-menu-closer"></div>
<a>Get Characters</a> <div class="content-menu">
</li> <div class="content-infos">
<li class="scroll-to-link" data-target="content-errors"> <div class="info"><b>Version:</b> 0</div>
<a>Errors</a> <div class="info"><b>Last Updated:</b> 22th January 2024</div>
</li> </div>
</ul> <ul>
</div> <li class="scroll-to-link active" data-target="content-get-started">
</div> <a>GET STARTED</a>
</li>
<li class="scroll-to-link" data-target="content-get-characters">
<a>Get Data From API</a>
</li>
<li class="scroll-to-link" data-target="content-errors">
<a>Errors</a>
</li>
</ul>
</div>
</div>
<div class="content-page"> <div class="content-page">
<div class="content"> <div class="content">
<div class="overflow-hidden content-section" id="content-get-started"> <div class="overflow-hidden content-section" id="content-get-started">
<h1>Get started</h1> <h1>Get started</h1>
<p> <p>
The Westeros API provides programmatic access to read Game of Thrones data. Retrieve a character, provide an oauth connexion, retrieve a familly, filter them, etc. The following API is provided by the Eco saver developer team. It allows you to get Location and
</p> Sensor and Sensor Data from the Eco saver database.
<p> </p>
To use this API, you need an <strong>API key</strong>. Please contact us at <a href="mailto:jon.snow@nightswatch.wes">jon.snow@nightswatch.wes</a> to get your own API key. <p>
</p> To use this API, you need an <strong>API key</strong>.
</div> </p>
<div class="overflow-hidden content-section" id="content-get-characters"> </div>
<h2>get characters</h2> <div class="overflow-hidden content-section" id="content-get-location">
<p> <h2>Get all location</h2>
To get characters you need to make a POST call to the following url :<br> <p>
<code class="higlighted break-word">http://api.westeros.com/character/get</code> To get Location of sensors you need to make a GET call to the following url :<br>
</p> <code class="higlighted break-word">https://api.teeseng.uk/api/v0/location</code>
<br> <br>
<h4>QUERY PARAMETERS</h4> <br>
<table> Return Response :<br>
<thead> <code class="higlighted break-word">{"status":"200"}</code>
<tr> </p>
<th>Field</th> <br>
<th>Type</th> <h4>QUERY PARAMETERS</h4>
<th>Description</th> <table>
</tr> <thead>
</thead> <tr>
<tbody> <th>Field</th>
<tr> <th>Type</th>
<td>secret_key</td> <th>Description</th>
<td>String</td> </tr>
<td>Your API key.</td> </thead>
</tr> <tbody>
<tr> <tr>
<td>search</td> <td>Authorization</td>
<td>String</td> <td>JSON</td>
<td>(optional) A search word to find character by name.</td> <td>Your API key.</td>
</tr> <td>(Required) Example: curl https://api.teeseng.uk/api/v0/location -H "Authorization: {provide your
<tr> API key here}"</td>
<td>house</td> </td>
<td>String</td> </tr>
<td> </tbody>
(optional) a string array of houses: </table>
</td> </div>
</tr> <div class="overflow-hidden content-section" id="content-get-location-by-id">
<tr> <h2>Get location by ID</h2>
<td>alive</td> <p>
<td>Boolean</td> To get Location you need to make a GET call to the following url :<br>
<td> <code class="higlighted break-word">https://api.teeseng.uk/api/v0/location/{id}</code>
(optional) a boolean to filter alived characters <br>
</td> <br>
</tr> Return Response :<br>
<tr> <code class="higlighted break-word">{"status":"200"}</code>
<td>gender</td> </p>
<td>String</td> <br>
<td> <h4>QUERY PARAMETERS</h4>
(optional) a string to filter character by gender:<br> m: male<br> f: female <table>
</td> <thead>
</tr> <tr>
<tr> <th>Field</th>
<td>offset</td> <th>Type</th>
<td>Integer</td> <th>Description</th>
<td>(optional - default: 0) A cursor for use in pagination. Pagination starts offset the specified offset.</td> </tr>
</tr> </thead>
<tr> <tbody>
<td>limit</td> <tr>
<td>Integer</td> <td>Authorization</td>
<td>(optional - default: 10) A limit on the number of objects to be returned, between 1 and 100.</td> <td>JSON</td>
</tr> <td>(Required) Your API key.</td>
</tbody> <td>Example: curl https://api.teeseng.uk/api/v0/location -H "Authorization: {provide your
</table> API key here}"</td>
</div> </td>
<div class="overflow-hidden content-section" id="content-errors"> </tr>
<h2>Errors</h2> </tbody>
<p> </table>
The Westeros API uses the following error codes: </div>
</p> <div class="overflow-hidden content-section" id="content-add-location">
<table> <h2>Add Location (Only for system or admin API key)</h2>
<thead> <p>
<tr> To add an Location you need to make a POST call to the following url :<br>
<th>Error Code</th> <code class="higlighted break-word">https://api.teeseng.uk/api/v0/location/new</code>
<th>Meaning</th> <br>
</tr> <br>
</thead> Example :<br>
<tbody> <code class="higlighted break-word">curl https://api.teeseng.uk/api/v0/location/new -H "Content-Type: application/json" -X POST -d '{"name": "SAMPLE", "added_by": "system" , "description": "test"}'</code>
<tr> <br>
<td>X000</td> <br>
<td> Return Response :<br>
Some parameters are missing. This error appears when you don't pass every mandatory parameters. <code class="higlighted break-word">{"status":"200"}</code>
</td> </p>
</tr> <br>
<tr> <h4>QUERY PARAMETERS</h4>
<td>X001</td> <table>
<td> <thead>
Unknown or unvalid <code class="higlighted">secret_key</code>. This error appears if you use an unknow API key or if your API key expired. <tr>
</td> <th>Field</th>
</tr> <th>Type</th>
<tr> <th>Description</th>
<td>X002</td> </tr>
<td> </thead>
Unvalid <code class="higlighted">secret_key</code> for this domain. This error appears if you use an API key non specified for your domain. Developper or Universal API keys doesn't have domain checker. <tbody>
</td> <tr>
</tr> <td>Authorization</td>
<tr> <td>JSON</td>
<td>X003</td> <td>Your API key.</td>
<td> <td>(Required) Example: curl https://api.teeseng.uk/api/v0/location/new -H "Authorization: {provide your
Unknown or unvalid user <code class="higlighted">token</code>. This error appears if you use an unknow user <code class="higlighted">token</code> or if the user <code class="higlighted">token</code> expired. API key here}"</td>
</td> </td>
</tr> </tr>
</tbody> <tr>
</table> <td>Location name</td>
</div> <td>JSON</td>
</div> <td>Location name.</td>
</div> <td>(Required) Location name. Example: curl https://api.teeseng.uk/api/v0/location/new -H "Authorization: provide
your API key here" -d '{"name":"Location name"}'</td>
</td>
</tr>
<tr>
<td>Added by </td>
<td>JSON</td>
<td>System or Admin</td>
<td>(Required) System or Admin Example: curl https://api.teeseng.uk/api/v0/location/new -H "Authorization: provide
your API key here" -d '{"added_by":"system"}'</td>
</td>
</tr>
<tr>
<td>Description</td>
<td>JSON</td>
<td>Description of Location</td>
<td>(Required) System or Admin Example: curl https://api.teeseng.uk/api/v0/location/new -H "Authorization: provide
your API key here" -d '{"description":"test"}'</td>
</td>
</tr>
</tbody>
</table>
</div>
<!-- update -->
<div class="overflow-hidden content-section" id="content-update-location-by-id">
<h2>Update Location (Only for system or admin API key)</h2>
<p>
To update an Location you need to make a PUT call to the following url :<br>
<code class="higlighted break-word">https://api.teeseng.uk/api/v0/location/update</code>
<br>
<br>
Example :<br>
<code class="higlighted break-word">curl https://api.teeseng.uk/api/v0/location/update -H "Content-Type: application/json" -X POST -d '{"id": "7" , "name": "SAMPLE", "added_by": "system" , "description": "test"}'</code>
<br>
<br>
Return Response :<br>
<code class="higlighted break-word">{"status":"200","message":"Location 7 updated"}</code>
</p>
<br>
<h4>QUERY PARAMETERS</h4>
<table>
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Authorization</td>
<td>JSON</td>
<td>Your API key.</td>
<td>(Required) example: curl https://api.teeseng.uk/api/v0/location/update -H "Authorization: {provide your
API key here}"</td>
</td>
</tr>
<tr>
<td>ID</td>
<td>JSON</td>
<td>Location ID</td>
<td>(Required) Location ID Example: curl https://api.teeseng.uk/api/v0/location/update -H "Authorization: provide
your API key here" -d '{"id": "7"}'</td>
</td>
</tr>
<tr>
<td>Location name</td>
<td>JSON</td>
<td>Location name.</td>
<td>(Optional) Location name. Example: curl https://api.teeseng.uk/api/v0/location/new -H "Authorization: provide
your API key here" -d '{"name":"Location name"}'</td>
</td>
</tr>
<tr>
<td>Added by </td>
<td>JSON</td>
<td>System or Admin</td>
<td>(Optional) System or Admin Example: curl https://api.teeseng.uk/api/v0/location/new -H "Authorization: provide
your API key here" -d '{"added_by":"system"}'</td>
</td>
</tr>
<tr>
<td>Description</td>
<td>JSON</td>
<td>Description of Location</td>
<td>(Optional) System or Admin Example: curl https://api.teeseng.uk/api/v0/location/new -H "Authorization: provide
your API key here" -d '{"description":"test"}'</td>
</td>
</tr>
</tbody>
</table>
</div>
<!-- delete location -->
<div class="overflow-hidden content-section" id="content-update-location-by-id">
<h2>Delete Location (Only for system or admin API key)</h2>
<p>
To delete an Location you need to make a DELETE call to the following url :<br>
<code class="higlighted break-word">https://api.teeseng.uk/api/v0/location/delete</code>
<br>
<br>
Example :<br>
<code class="higlighted break-word">curl https://api.teeseng.uk/api/v0/location/delete -H "Content-Type: application/json" -X POST -d '{"id": "7"}'</code>
</p>
<br>
<h4>QUERY PARAMETERS</h4>
<table>
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Authorization</td>
<td>JSON</td>
<td>Your API key.</td>
<td>(Required) example: curl https://api.teeseng.uk/api/v0/location/delete -H "Authorization: {provide your
API key here}"</td>
</td>
</tr>
<tr>
<td>ID</td>
<td>JSON</td>
<td>Location ID</td>
<td>(Required) Location ID Example: curl https://api.teeseng.uk/api/v0/location/delete -H "Authorization: provide
your API key here" -d '{"id": "7"}'</td>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
<div class="overflow-hidden content-section" id="content-errors">
<h2>Errors</h2>
<p>
The Westeros API uses the following error codes:
</p>
<table>
<thead>
<tr>
<th>Error Code</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td>X000</td>
<td>
Some parameters are missing. This error appears when you don't pass every mandatory
parameters.
</td>
</tr>
<tr>
<td>403</td>
<td>
Unknown or unvalid <code class="higlighted">secret_key</code>. This error appears if
you use an unknow API key or if your API key expired.
</td>
</tr>
<tr>
<td>500</td>
<td>
Unvalid <code class="higlighted">secret_key</code> No API key was supplied. Invalid
request.
</td>
</tr>
<tr>
<td>X003</td>
<td>
Unknown or unvalid user <code class="higlighted">token</code>. This error appears if
you use an unknow user <code class="higlighted">token</code> or if the user <code
class="higlighted">token</code> expired.
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>

View File

@ -1,39 +1,45 @@
const { checkAPikey } = require('../functions/database.js'); const { checkAPikey } = require("../functions/database.js");
async function apikeyCheck(req, res, next) { async function apikeyCheck(req, res, next) {
//const authHeader = req.headers.authorization //const authHeader = req.headers.authorization
try{ try {
let apikey = req.headers.authorization let apikey = req.headers.authorization;
if(!apikey){ if (!apikey) {
throw new Error('No API key was supplied. Invalid request') res.status(401).json({
} message: "No API key was supplied. Invalid request",
else{ });
//split the string by the - //throw new Error("No API key was supplied. Invalid request");
let splitAPIkey = apikey.split('-'); } else {
let rowid = splitAPIkey[0]; //split the string by the -
let splitAPIkey = apikey.split("-");
//rejoin withouth the rowid let rowid = splitAPIkey[0];
let SuppliedKey = splitAPIkey.slice(1).join('-');
if (checkAPikey(SuppliedKey , rowid))
{
//get permission
let permission = await checkAPikey(SuppliedKey , rowid);
console.log(permission);
if (req.method === 'GET' && permission === 'canRead'){
return next()
}
//['POST', 'PUT', 'PATCH', 'DELETE'].includes(req.method)
if (["GET" , "POST" , "PUT" , "DELETE"].includes(req.method) && permission === 'canWrite'){
console.log('write')
return next()
}
throw new Error('Your API key does not have the correct permissions to access this resource')
}
}
}catch(error){
next(error);
}
//rejoin withouth the rowid
let SuppliedKey = splitAPIkey.slice(1).join("-");
if (checkAPikey(SuppliedKey, rowid)) {
//get permission
let permission = await checkAPikey(SuppliedKey, rowid);
console.log(permission);
if (req.method === "GET" && permission === "canRead") {
return next();
}
//['POST', 'PUT', 'PATCH', 'DELETE'].includes(req.method)
if (
["GET", "POST", "PUT", "DELETE"].includes(req.method) &&
permission === "canWrite"
) {
console.log("write");
return next();
}
//throw status 403
res.status(403).json({
message:
"Your API key does not have the correct permissions to access this resource",
});
}
}
} catch (error) {
next(error);
}
} }
module.exports = { apikeyCheck }; module.exports = { apikeyCheck };