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">
<div class="content-page"> <a>Get Data From API</a>
<div class="content"> </li>
<div class="overflow-hidden content-section" id="content-get-started"> <li class="scroll-to-link" data-target="content-errors">
<h1>Get started</h1> <a>Errors</a>
<p> </li>
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. </ul>
</p> </div>
<p> </div>
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>
</div>
<div class="overflow-hidden content-section" id="content-get-characters">
<h2>get characters</h2>
<p>
To get characters you need to make a POST call to the following url :<br>
<code class="higlighted break-word">http://api.westeros.com/character/get</code>
</p>
<br>
<h4>QUERY PARAMETERS</h4>
<table>
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>secret_key</td>
<td>String</td>
<td>Your API key.</td>
</tr>
<tr>
<td>search</td>
<td>String</td>
<td>(optional) A search word to find character by name.</td>
</tr>
<tr>
<td>house</td>
<td>String</td>
<td>
(optional) a string array of houses:
</td>
</tr>
<tr>
<td>alive</td>
<td>Boolean</td>
<td>
(optional) a boolean to filter alived characters
</td>
</tr>
<tr>
<td>gender</td>
<td>String</td>
<td>
(optional) a string to filter character by gender:<br> m: male<br> f: female
</td>
</tr>
<tr>
<td>offset</td>
<td>Integer</td>
<td>(optional - default: 0) A cursor for use in pagination. Pagination starts offset the specified offset.</td>
</tr>
<tr>
<td>limit</td>
<td>Integer</td>
<td>(optional - default: 10) A limit on the number of objects to be returned, between 1 and 100.</td>
</tr>
</tbody>
</table>
</div>
<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>X001</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>X002</td>
<td>
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.
</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>
<div class="content-page">
<div class="content">
<div class="overflow-hidden content-section" id="content-get-started">
<h1>Get started</h1>
<p>
The following API is provided by the Eco saver developer team. It allows you to get Location and
Sensor and Sensor Data from the Eco saver database.
</p>
<p>
To use this API, you need an <strong>API key</strong>.
</p>
</div>
<div class="overflow-hidden content-section" id="content-get-location">
<h2>Get all location</h2>
<p>
To get Location of sensors you need to make a GET call to the following url :<br>
<code class="higlighted break-word">https://api.teeseng.uk/api/v0/location</code>
<br>
<br>
Return Response :<br>
<code class="higlighted break-word">{"status":"200"}</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 -H "Authorization: {provide your
API key here}"</td>
</td>
</tr>
</tbody>
</table>
</div>
<div class="overflow-hidden content-section" id="content-get-location-by-id">
<h2>Get location by ID</h2>
<p>
To get Location you need to make a GET call to the following url :<br>
<code class="higlighted break-word">https://api.teeseng.uk/api/v0/location/{id}</code>
<br>
<br>
Return Response :<br>
<code class="higlighted break-word">{"status":"200"}</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>(Required) Your API key.</td>
<td>Example: curl https://api.teeseng.uk/api/v0/location -H "Authorization: {provide your
API key here}"</td>
</td>
</tr>
</tbody>
</table>
</div>
<div class="overflow-hidden content-section" id="content-add-location">
<h2>Add Location (Only for system or admin API key)</h2>
<p>
To add an Location you need to make a POST call to the following url :<br>
<code class="higlighted break-word">https://api.teeseng.uk/api/v0/location/new</code>
<br>
<br>
Example :<br>
<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>
<br>
<br>
Return Response :<br>
<code class="higlighted break-word">{"status":"200"}</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/new -H "Authorization: {provide your
API key here}"</td>
</td>
</tr>
<tr>
<td>Location name</td>
<td>JSON</td>
<td>Location name.</td>
<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>
<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 };
@ -56,4 +62,4 @@ If it's correct API key and has canWrite perms
I allow it to access put and post I allow it to access put and post
*/ */