Add nodemailer configuration and console.log statement
Update formAJAX function to log data from the server Add getUserByEmail and checkEmail functions Update profile.ejs to require login Update addSensorData function to emit new sensor data Update api.css with styling changes Update token route to generate and send token email Update authChecker middleware to allow user and token routes
This commit is contained in:
parent
818d90b440
commit
c234aa3616
82
consumerWebsite/functions/nodeMail.js
Normal file
82
consumerWebsite/functions/nodeMail.js
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
const { transporter } = require("../modules/nodemailer");
|
||||||
|
const path = require("path");
|
||||||
|
require("dotenv").config({ path: path.resolve(__dirname, "../.env") });
|
||||||
|
|
||||||
|
/*
|
||||||
|
var message = {
|
||||||
|
from: "sender@server.com",
|
||||||
|
to: "receiver@sender.com",
|
||||||
|
subject: "Message title",
|
||||||
|
text: "Plaintext version of the message",
|
||||||
|
html: "<p>HTML version of the message</p>",
|
||||||
|
};
|
||||||
|
//send mail with defined transport object
|
||||||
|
transporter.sendMail(data[, callback])
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
async function sendContactEmail(email, name, message) {
|
||||||
|
console.log(email, name, message);
|
||||||
|
|
||||||
|
try {
|
||||||
|
let contactMessage = await transporter.sendMail({
|
||||||
|
to: process.env.euser,
|
||||||
|
subject: "Contact us Message",
|
||||||
|
html: `
|
||||||
|
<h1>Contact us Message</h1>
|
||||||
|
<p><strong>From:</strong> ${name}</p>
|
||||||
|
<p><strong>User Email:</strong> ${email}</p>
|
||||||
|
<p><strong>Message:</strong> ${message}</p>
|
||||||
|
<p>Thank you for contacting us. We will get back to you as soon as possible.</p>
|
||||||
|
<p>Regards,</p>
|
||||||
|
<p>EcoSaver Team</p>
|
||||||
|
<p><a href="https://ecosaver.teeseng.uk/">EcoSaver Website</a></p>
|
||||||
|
<p>Please do not reply to this email.</p>
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
transporter.sendMail({ contactMessage }, function (error, info) {
|
||||||
|
if (error) {
|
||||||
|
console.log(error);
|
||||||
|
} else {
|
||||||
|
console.log("Email sent: " + info.response);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sendTokenEmail(email, token) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
let tokenMessage = await transporter.sendMail({
|
||||||
|
to: email,
|
||||||
|
from: process.env.euser,
|
||||||
|
subject: "API Token",
|
||||||
|
html: `
|
||||||
|
<h1>API Token</h1>
|
||||||
|
<p><strong>Token:</strong> ${token}</p>
|
||||||
|
<p>Please do not lose this token and do not share your token with anyone!</p>
|
||||||
|
<p>Thank you for using EcoSaver.</p>
|
||||||
|
<p>Regards,</p>
|
||||||
|
<p>EcoSaver Team</p>
|
||||||
|
<p><a href="https://ecosaver.teeseng.uk/">EcoSaver Website</a></p>
|
||||||
|
<p>Please do not reply to this email.</p>
|
||||||
|
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
transporter.sendMail({ tokenMessage }, function (error, info) {
|
||||||
|
if (error) {
|
||||||
|
console.log(error);
|
||||||
|
} else {
|
||||||
|
console.log("Email sent: " + info.response);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = { sendContactEmail , sendTokenEmail };
|
@ -18,7 +18,6 @@ async function getSensorData() {
|
|||||||
const sensorData = await sensorDataModel.findAll();
|
const sensorData = await sensorDataModel.findAll();
|
||||||
return sensorData;
|
return sensorData;
|
||||||
}
|
}
|
||||||
let dataArray = [];
|
|
||||||
async function addSensorData(id_sensor, id_location, sensordata) {
|
async function addSensorData(id_sensor, id_location, sensordata) {
|
||||||
const sensorData = await sensorDataModel.create({
|
const sensorData = await sensorDataModel.create({
|
||||||
sensorid: id_sensor,
|
sensorid: id_sensor,
|
||||||
@ -26,11 +25,10 @@ async function addSensorData(id_sensor, id_location, sensordata) {
|
|||||||
measurement: sensordata.measurement,
|
measurement: sensordata.measurement,
|
||||||
});
|
});
|
||||||
//console.log("sensorData", sensorData);
|
//console.log("sensorData", sensorData);
|
||||||
//console.log("sensorData", sensordata);
|
//console.log("sensorData", sensordata.measurement);
|
||||||
dataArray.push(sensordata);
|
|
||||||
console.log("dataArray", dataArray);
|
|
||||||
|
|
||||||
io().emit('sensorData:new', dataArray)
|
|
||||||
|
io().emit('sensorData:new', sensordata)
|
||||||
return sensorData;
|
return sensorData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +66,7 @@ async function getSensorDataById(id) {
|
|||||||
|
|
||||||
async function getLatestData() {
|
async function getLatestData() {
|
||||||
const sensorData = await sensorDataModel.findAll({
|
const sensorData = await sensorDataModel.findAll({
|
||||||
limit: 1,
|
limit: 6,
|
||||||
order: [["createdAt", "DESC"]],
|
order: [["createdAt", "DESC"]],
|
||||||
});
|
});
|
||||||
return sensorData;
|
return sensorData;
|
||||||
|
@ -20,6 +20,16 @@ async function getUserByID(userid) {
|
|||||||
return userRes;
|
return userRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getUserByEmail(email) {
|
||||||
|
let userRes = await userModel.findOne({
|
||||||
|
where: {
|
||||||
|
email: email,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!userRes) return false;
|
||||||
|
return userRes;
|
||||||
|
}
|
||||||
|
|
||||||
//api/v0/auth/register
|
//api/v0/auth/register
|
||||||
/* Registering new user
|
/* Registering new user
|
||||||
1) req.body is taken from html form or wtv
|
1) req.body is taken from html form or wtv
|
||||||
@ -131,9 +141,23 @@ async function updateProfile(user, body) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function checkEmail(email) {
|
||||||
|
let emailRes = await userModel.findOne({
|
||||||
|
where: {
|
||||||
|
email: email,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!emailRes) return false;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getUserByID,
|
getUserByID,
|
||||||
|
getUserByEmail,
|
||||||
addUser,
|
addUser,
|
||||||
loginUser,
|
loginUser,
|
||||||
updateProfile,
|
updateProfile,
|
||||||
|
checkEmail
|
||||||
};
|
};
|
@ -19,12 +19,24 @@ async function auth(req, res, next) {
|
|||||||
|
|
||||||
const route = req.originalUrl.split("?")[0]; // Removing query parameters
|
const route = req.originalUrl.split("?")[0]; // Removing query parameters
|
||||||
//if route is from user/ and permission is canRead allow it to do CRUD
|
//if route is from user/ and permission is canRead allow it to do CRUD
|
||||||
if (route.includes("/user/") && token.permission === "canRead") {
|
if (route.includes("/user/") || route.includes("/token/") && token.permission === "canRead") {
|
||||||
|
console.log("user route");
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
if ((req.method === "GET" && token.permission === "canRead") || (["GET", "POST", "PUT", "DELETE"].includes(req.method) && token.permission === "canWrite")) {
|
if ((req.method === "GET" && token.permission === "canRead")){
|
||||||
|
console.log("wtf you shldnt be here");
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
if (["GET", "POST", "PUT", "DELETE"].includes(req.method) && token.permission === "canWrite") {
|
||||||
|
console.log("wtf you shldnt be here");
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if ((req.method === "GET" && token.permission === "canRead") ||
|
||||||
|
(["GET", "POST", "PUT", "DELETE"].includes(req.method) && token.permission === "canWrite")) {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
throw permissionError
|
throw permissionError
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ const nodemailer = require("nodemailer");
|
|||||||
const dotenv = require("dotenv");
|
const dotenv = require("dotenv");
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
require('dotenv').config({ path: path.resolve(__dirname, '../.env') })
|
require('dotenv').config({ path: path.resolve(__dirname, '../.env') })
|
||||||
|
//.env
|
||||||
|
|
||||||
let transporter = nodemailer.createTransport({
|
let transporter = nodemailer.createTransport({
|
||||||
service: 'gmail',
|
service: 'gmail',
|
||||||
|
@ -528,22 +528,24 @@ body.one-content-column-version .content thead {
|
|||||||
|
|
||||||
|
|
||||||
.generate-key-button {
|
.generate-key-button {
|
||||||
float: right; /* Align the button to the right */
|
margin-top: -40px;
|
||||||
margin-right: 85%;
|
margin-left: 25px;
|
||||||
margin-top: -40px; /* Adjust the margin-top value based on your layout */
|
|
||||||
/* Add any additional styling you want for the button */
|
|
||||||
}
|
|
||||||
|
|
||||||
#content-get-api .generate-key-button {
|
|
||||||
background-color: #4caf50; /* Green background color */
|
background-color: #4caf50; /* Green background color */
|
||||||
color: white; /* White text color */
|
color: #ffffff;
|
||||||
padding: 5px 11px; /* Padding for the button */
|
padding: 5px 11px; /* Padding for the button */
|
||||||
border: none; /* Remove button border */
|
border: none; /* Remove button border */
|
||||||
border-radius: 5px; /* Add border-radius for rounded corners */
|
border-radius: 5px; /* Add border-radius for rounded corners */
|
||||||
cursor: pointer; /* Add pointer cursor on hover */
|
cursor: pointer; /* Add pointer cursor on hover */
|
||||||
font-size: 14px; /* Font size */
|
font-size: 14px; /* Font size */
|
||||||
}
|
}
|
||||||
|
.api-form {
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-left: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
#content-get-api .generate-key-button:hover {
|
.generate-key-button:hover {
|
||||||
background-color: #45a049; /* Darker green on hover */
|
background-color: #45a049; /* Darker green on hover */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -285,7 +285,7 @@ function formAJAX(btn, del) {
|
|||||||
//console.log('Data being sent to', $form.attr('action'), formData)
|
//console.log('Data being sent to', $form.attr('action'), formData)
|
||||||
|
|
||||||
app.api[method]($form.attr("action"), formData, function (error, data) {
|
app.api[method]($form.attr("action"), formData, function (error, data) {
|
||||||
//console.log('Data back from the server', error, data)
|
console.log('Data back from the server', error, data)
|
||||||
app.util.actionMessage(data.message, $form, error ? "danger" : "success"); //re-populate table
|
app.util.actionMessage(data.message, $form, error ? "danger" : "success"); //re-populate table
|
||||||
if (!error) {
|
if (!error) {
|
||||||
$form.trigger("reset");
|
$form.trigger("reset");
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
const { addUser, loginUser } = require("../functions/user");
|
const { addUser, loginUser, checkEmail } = require("../functions/user");
|
||||||
|
const { sendContactEmail } = require("../functions/nodeMail");
|
||||||
|
|
||||||
const express = require("express");
|
const express = require("express");
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
@ -12,12 +13,11 @@ router.post("/register", async (req, res, next) => {
|
|||||||
error.message = "The user failed to be craated";
|
error.message = "The user failed to be craated";
|
||||||
error.status = 400;
|
error.status = 400;
|
||||||
return next(error);
|
return next(error);
|
||||||
|
} else {
|
||||||
|
return res.json({
|
||||||
|
message: "User created successfully",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else{
|
|
||||||
return res.json({
|
|
||||||
message: "User created successfully",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
next(error);
|
next(error);
|
||||||
@ -29,20 +29,18 @@ router.post("/login", async (req, res, next) => {
|
|||||||
try {
|
try {
|
||||||
let Res = await loginUser(req.body);
|
let Res = await loginUser(req.body);
|
||||||
if (Res == false) {
|
if (Res == false) {
|
||||||
let error = new Error("User Login Failed");
|
let error = new Error("User Login Failed");
|
||||||
error.status = 400;
|
error.status = 400;
|
||||||
return next(error);
|
return next(error);
|
||||||
|
} else {
|
||||||
|
//pass res back to form to be set in local storage
|
||||||
|
return res.json({
|
||||||
|
message: "User login successfully",
|
||||||
|
token: Res.token,
|
||||||
|
userid: Res.userid,
|
||||||
|
username: Res.username,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else{
|
|
||||||
//pass res back to form to be set in local storage
|
|
||||||
return res.json({
|
|
||||||
message: "User login successfully",
|
|
||||||
token: Res.token,
|
|
||||||
userid: Res.userid,
|
|
||||||
username: Res.username,
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
next(error);
|
next(error);
|
||||||
@ -52,8 +50,26 @@ router.post("/login", async (req, res, next) => {
|
|||||||
//contact
|
//contact
|
||||||
//auth/contact
|
//auth/contact
|
||||||
router.post("/contact", async (req, res, next) => {
|
router.post("/contact", async (req, res, next) => {
|
||||||
|
try {
|
||||||
|
//console.log(req.body);
|
||||||
|
let Res = await checkEmail(req.body.email);
|
||||||
|
if (!Res) {
|
||||||
|
let error = new Error("Email not found");
|
||||||
|
error.status = 400;
|
||||||
|
return next(error);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
//console.log(Res);
|
||||||
|
sendContactEmail(req.body.email, req.body.name, req.body.message);
|
||||||
|
return res.json({
|
||||||
|
message: "Email sent successfully",
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
next(error);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
const { addToken } = require("../functions/api");
|
const { addToken } = require("../functions/api");
|
||||||
|
const { checkEmail , getUserByEmail } = require("../functions/user");
|
||||||
|
const { sendTokenEmail } = require("../functions/nodeMail");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const express = require("express");
|
const express = require("express");
|
||||||
@ -15,8 +18,29 @@ const router = express.Router();
|
|||||||
//'{"userid": "5", "permission": "canRead" ,}'
|
//'{"userid": "5", "permission": "canRead" ,}'
|
||||||
router.post("/new", async (req, res, next) => {
|
router.post("/new", async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const token = await addToken(req.body.userid, req.body.permission , "2204-01-24 07:34:36" );
|
//console.log(req.body);
|
||||||
res.json({token: token});
|
const Res = await checkEmail(req.body.email);
|
||||||
|
if (!Res) {
|
||||||
|
let error = new Error("Email not found");
|
||||||
|
error.status = 400;
|
||||||
|
return next(error);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//console.log("email found");
|
||||||
|
let userid = await getUserByEmail(req.body.email);
|
||||||
|
if (!userid) return false;
|
||||||
|
|
||||||
|
const token = await addToken(userid.id, "canRead" , "2204-01-24 07:34:36" );
|
||||||
|
if (!token) return false;
|
||||||
|
sendTokenEmail(req.body.email, token);
|
||||||
|
res.json({
|
||||||
|
message: "Token generated successfully and sent to email",
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
//const token = await addToken(req.body.userid, "canRead" , "2204-01-24 07:34:36" );
|
||||||
|
//res.json({token: token});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
next(error);
|
next(error);
|
||||||
|
@ -6,6 +6,10 @@
|
|||||||
!-->
|
!-->
|
||||||
|
|
||||||
<%- include('top') %>
|
<%- include('top') %>
|
||||||
|
<script type="text/javascript">
|
||||||
|
// Require login to see this page.
|
||||||
|
app.auth.forceLogin()
|
||||||
|
</script>
|
||||||
<link rel="stylesheet" href="css/api.css" media="all">
|
<link rel="stylesheet" href="css/api.css" media="all">
|
||||||
|
|
||||||
<body class="one-content-column-version">
|
<body class="one-content-column-version">
|
||||||
@ -312,81 +316,6 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</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 class="overflow-hidden content-section" id="content-get-api">
|
|
||||||
<div class="api-keys-header">
|
|
||||||
<h2>API Keys</h2>
|
|
||||||
<button class="generate-key-button">Generate Key</button>
|
|
||||||
<p>
|
|
||||||
You can generate API Keys here:
|
|
||||||
</p>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Public Key</th>
|
|
||||||
<th>Private Key</th>
|
|
||||||
<th>Key Type</th>
|
|
||||||
<th>Created</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>API Key</td>
|
|
||||||
<td>GR234-We34</td>
|
|
||||||
<td>greR-234-fEG</td>
|
|
||||||
<td>Type</td>
|
|
||||||
<td>2024-01-22</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="overflow-hidden content-section" id="content-get-sensor">
|
<div class="overflow-hidden content-section" id="content-get-sensor">
|
||||||
<h2>Get all sensor</h2>
|
<h2>Get all sensor</h2>
|
||||||
<p>
|
<p>
|
||||||
@ -620,7 +549,8 @@
|
|||||||
<td>Description</td>
|
<td>Description</td>
|
||||||
<td>JSON</td>
|
<td>JSON</td>
|
||||||
<td>Description of Sensor</td>
|
<td>Description of Sensor</td>
|
||||||
<td>(Optional) Description of Sensor Example: curl https://api.teeseng.uk/api/v0/sensor/update
|
<td>(Optional) Description of Sensor Example: curl
|
||||||
|
https://api.teeseng.uk/api/v0/sensor/update
|
||||||
-H "Authorization: provide
|
-H "Authorization: provide
|
||||||
your API key here" -d '{"description":"test"}'</td>
|
your API key here" -d '{"description":"test"}'</td>
|
||||||
</td>
|
</td>
|
||||||
@ -629,7 +559,8 @@
|
|||||||
<td>Location</td>
|
<td>Location</td>
|
||||||
<td>JSON</td>
|
<td>JSON</td>
|
||||||
<td>Location of Sensor</td>
|
<td>Location of Sensor</td>
|
||||||
<td>(Optional) Location of Sensor Example: curl https://api.teeseng.uk/api/v0/sensor/update
|
<td>(Optional) Location of Sensor Example: curl
|
||||||
|
https://api.teeseng.uk/api/v0/sensor/update
|
||||||
-H "Authorization: provide
|
-H "Authorization: provide
|
||||||
your API key here" -d '{"location": "11"}'</td>
|
your API key here" -d '{"location": "11"}'</td>
|
||||||
</td>
|
</td>
|
||||||
@ -679,10 +610,77 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<div class="api-keys-header iot-card" id="content-get-api">
|
||||||
|
<h2>API Keys</h2>
|
||||||
|
<p>
|
||||||
|
You can generate API Keys here:
|
||||||
|
</p>
|
||||||
|
<form action="token/new" onsubmit="formAJAX(this)" class="api-form">
|
||||||
|
<div class="card-header shadow actionMessage" style="display:none;"></div>
|
||||||
|
<input type="email" name="email" id="email" placeholder="Email address"
|
||||||
|
pattern="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*">
|
||||||
|
<div style="margin-top: 10px;"></div>
|
||||||
|
<button class="generate-key-button">Generate Key</button>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="overflow-hidden content-section" id="content-errors">
|
||||||
|
<h2>Errors</h2>
|
||||||
|
<p>
|
||||||
|
The EcoSaver 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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
<script src="js/api.js"></script>
|
<script src="js/api.js"></script>
|
||||||
|
|
||||||
</html>
|
</html>
|
@ -42,7 +42,8 @@
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<abbr title="Email">E</abbr>:
|
<abbr title="Email">E</abbr>:
|
||||||
<a href="mailto:name@example.com">leongdingxuan@gmail.com
|
<a href="mailto:name@example.com">ecosaverx@gmail.com
|
||||||
|
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
@ -55,17 +56,18 @@
|
|||||||
<!-- Contact Form -->
|
<!-- Contact Form -->
|
||||||
<!-- In order to set the email address and subject line for the contact form go to the bin/contact_me.php file. -->
|
<!-- In order to set the email address and subject line for the contact form go to the bin/contact_me.php file. -->
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
<div class="form contact iot-card">
|
||||||
<div class="col-lg-8 mb-4 contact-left">
|
<div class="col-lg-8 mb-4 contact-left">
|
||||||
<h3>Send us a Message</h3>
|
<h3>Send us a Message</h3>
|
||||||
<form id="form">
|
<form action="auth/contact" onsubmit="formAJAX(this)">
|
||||||
<input type="hidden" name="access_key" value="">
|
<div class="card-header shadow actionMessage" style="display:none"></div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="name">Full Name</label>
|
<label for="name">Full Name</label>
|
||||||
<input type="text" name="name" id="name" required>
|
<input type="text" name="name" id="name" required pattern="^[a-zA-Z]{3,}( {1,2}[a-zA-Z]{3,}){0,}$">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="email">Email address</label>
|
<label for="email">Email address</label>
|
||||||
<input type="email" name="email" id="email" required>
|
<input type="email" name="email" id="email" required pattern="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="message">Message</label>
|
<label for="message">Message</label>
|
||||||
@ -75,6 +77,8 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!-- /.row -->
|
<!-- /.row -->
|
||||||
|
@ -1,18 +1,59 @@
|
|||||||
<%- include('top') %>
|
<%- include('top') %>
|
||||||
<script>
|
<script type="text/javascript">
|
||||||
|
function extractNumbers(str) {
|
||||||
|
if (typeof str === 'number') return str;
|
||||||
|
return str.match(/\d+/)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateAverage(numbers) {
|
||||||
|
if (numbers.length === 0) return 0
|
||||||
|
const sum = numbers.reduce((acc, num) => acc + num, 0);
|
||||||
|
return sum / numbers.length;
|
||||||
|
}
|
||||||
|
const values = {
|
||||||
|
psi: [],
|
||||||
|
humidity: [],
|
||||||
|
temperature: [],
|
||||||
|
windspeed: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
function parseRowToTemplace(row) {
|
||||||
|
values.psi.unshift(extractNumbers(row.measurement.psi))
|
||||||
|
values.humidity.unshift(extractNumbers(row.measurement.humidity))
|
||||||
|
values.temperature.unshift(extractNumbers(row.measurement.temperature))
|
||||||
|
values.windspeed.unshift(extractNumbers(row.measurement.windspeed))
|
||||||
|
|
||||||
|
return {
|
||||||
|
average: {
|
||||||
|
psi: parseInt(calculateAverage(values.psi)),
|
||||||
|
humidity: parseInt(calculateAverage(values.humidity)),
|
||||||
|
temperature: parseInt(calculateAverage(values.temperature)),
|
||||||
|
windspeed: parseInt(calculateAverage(values.windspeed)),
|
||||||
|
},
|
||||||
|
latest: {
|
||||||
|
psi: values.psi[0],
|
||||||
|
humidity: values.humidity[0],
|
||||||
|
temperature: values.temperature[0],
|
||||||
|
windspeed: values.windspeed[0],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$(document).ready(async function () {
|
$(document).ready(async function () {
|
||||||
|
|
||||||
app.api.get('latest-sensor-data/data', function (error, data) {
|
app.api.get('latest-sensor-data/data', function (error, data) {
|
||||||
//console.log(data[0]);
|
for (let row of data) {
|
||||||
$.scope.LatestSensorData.push(data[0]);
|
//console.log(row);
|
||||||
|
$.scope.LatestSensorData.update(parseRowToTemplace(row));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//call socket.io to get live data
|
||||||
|
app.socket.on("sensorData:new", function (data) {
|
||||||
|
$.scope.LatestSensorData.update(parseRowToTemplace(data));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
//call socket.io to get live data
|
|
||||||
app.socket.on("sensorData:new", function (data) {
|
|
||||||
|
|
||||||
console.log(data[0]);
|
|
||||||
$.scope.LatestSensorData.update(data[0]);
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -69,7 +110,8 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<h4 class="card-header">Air Quality Index</h4>
|
<h4 class="card-header">Air Quality Index</h4>
|
||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
<p class="card-text display-4">{{ measurement.psi }} PSI</p>
|
<p class="card-text display-4"> Average: {{average.psi}} PSI</p>
|
||||||
|
<p class="card-text display-4"> Latest: {{latest.psi}} PSI</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
<a href="/learnmore" class="btn btn-primary">Learn More</a>
|
<a href="/learnmore" class="btn btn-primary">Learn More</a>
|
||||||
@ -80,7 +122,8 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<h4 class="card-header">Humidity</h4>
|
<h4 class="card-header">Humidity</h4>
|
||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
<p class="card-text display-4">{{ measurement.humidity }} %</p>
|
<p class="card-text display-4"> Average: {{average.humidity}} %</p>
|
||||||
|
<p class="card-text display-4"> Latest: {{latest.humidity}} %</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
<a href="/learnmore" class="btn btn-primary">Learn More</a>
|
<a href="/learnmore" class="btn btn-primary">Learn More</a>
|
||||||
@ -91,7 +134,8 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<h4 class="card-header">Temperature</h4>
|
<h4 class="card-header">Temperature</h4>
|
||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
<p class="card-text display-4">{{ measurement.temperature }}°</p>
|
<p class="card-text display-4"> Average: {{average.temperature}}°</p>
|
||||||
|
<p class="card-text display-4"> Latest: {{latest.temperature}}°</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
<a href="/learnmore" class="btn btn-primary">Learn More</a>
|
<a href="/learnmore" class="btn btn-primary">Learn More</a>
|
||||||
@ -102,7 +146,8 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<h4 class="card-header">Wind Speed</h4>
|
<h4 class="card-header">Wind Speed</h4>
|
||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
<p class="card-text display-4">{{ measurement.windspeed }} Km/h </p>
|
<p class="card-text display-4"> Average: {{average.windspeed}} Km/h</p>
|
||||||
|
<p class="card-text display-4"> Latest: {{latest.windspeed}} Km/h</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
<a href="/learnmore" class="btn btn-primary">Learn More</a>
|
<a href="/learnmore" class="btn btn-primary">Learn More</a>
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/0.1/mustache.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/0.1/mustache.min.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/0.1/mustache.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/0.1/mustache.js"></script>
|
||||||
<!-- socket.io scriot -->
|
<!-- socket.io scriot -->
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.2.0/socket.io.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.2.0/socket.io.min.js"></script>
|
||||||
|
|
||||||
<!-- jquery app.js -->
|
<!-- jquery app.js -->
|
||||||
<script src="js/app.js"></script>
|
<script src="js/app.js"></script>
|
||||||
@ -44,19 +44,22 @@
|
|||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
//check if user is logged in
|
//check if user is logged in
|
||||||
app.auth.isLoggedIn(function (error, data) {
|
app.auth.isLoggedIn(function (error, data) {
|
||||||
if (data) {
|
if (!error) {
|
||||||
$('#cl-logout-button').show('fast');
|
$("#cl-logout-button").show("fast");
|
||||||
$('#cl-profile-button').show('fast');
|
$("#cl-api-button").show("fast");
|
||||||
$('#cl-login-button').hide('fast');
|
$("#cl-profile-button").show("fast");
|
||||||
|
$("#cl-login-button").hide("fast");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$('#cl-login-button').show('fast');
|
$('#cl-login-button').show('fast');
|
||||||
|
|
||||||
}
|
}
|
||||||
$('body').show('fast')
|
$('body').show('fast')
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-light top-nav fixed-top">
|
<nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-light top-nav fixed-top">
|
||||||
@ -79,11 +82,12 @@
|
|||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="/contact">Contact</a>
|
<a class="nav-link" href="/contact">Contact</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="/api">API Doc</a>
|
|
||||||
</li>
|
|
||||||
<!-- profile button -->
|
<!-- profile button -->
|
||||||
<div class="form-inline mt-2 mt-md-0">
|
<div class="form-inline mt-2 mt-md-0">
|
||||||
|
<a id="cl-api-button" class="btn btn-outline-info btn-sm my-2 my-sm-0" href="/api"
|
||||||
|
style="display: none">
|
||||||
|
<i class="fas fa-sign-out"></i> API
|
||||||
|
</a>
|
||||||
<a id="cl-profile-button" class="btn btn-outline-info my-2 my-sm-0" href="/profile"
|
<a id="cl-profile-button" class="btn btn-outline-info my-2 my-sm-0" href="/profile"
|
||||||
style="display: none;">
|
style="display: none;">
|
||||||
<i class="fas fa-sign-out"></i>
|
<i class="fas fa-sign-out"></i>
|
||||||
@ -104,4 +108,3 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
<%- include('top') %>
|
<%- include('top') %>
|
||||||
|
<script type="text/javascript">
|
||||||
|
// Require login to see this page.
|
||||||
|
app.auth.forceLogin()
|
||||||
|
</script>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
@ -6,9 +10,9 @@
|
|||||||
<div class="profile">
|
<div class="profile">
|
||||||
<!-- <li jq-repeat="getUsername" class="nav-item"> -->
|
<!-- <li jq-repeat="getUsername" class="nav-item"> -->
|
||||||
<div class="edit_information" jq-repeat="getUserDetails">
|
<div class="edit_information" jq-repeat="getUserDetails">
|
||||||
<div class="card-header shadow actionMessage" style="display:none"></div>
|
|
||||||
<form id="profileForm" action="user/update" method="put" onsubmit="formAJAX(this)"
|
<form id="profileForm" action="user/update" method="put" onsubmit="formAJAX(this)"
|
||||||
evalAJAX="app.auth.profileRedirect();">
|
evalAJAX="app.auth.profileRedirect();">
|
||||||
|
<div class="card-header shadow actionMessage" style="display:none"></div>
|
||||||
<h3 class="text-center">Edit Personal Information</h3>
|
<h3 class="text-center">Edit Personal Information</h3>
|
||||||
<br>
|
<br>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
277
example.html
Normal file
277
example.html
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
<%- include('top') %>
|
||||||
|
<style>
|
||||||
|
#sensorDataAverage {
|
||||||
|
padding-top: 2.5em;
|
||||||
|
padding-bottom: 2.5em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<div class="row" id="sensorDataAverage" jq-repeat='sensorDataAverage'>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div id="workerStatusCard" class="card shadow-lg">
|
||||||
|
<h5 class="card-header">
|
||||||
|
Air Quality Index
|
||||||
|
</h5>
|
||||||
|
<div class="card-body">
|
||||||
|
Average: {{average.aqi}}
|
||||||
|
<br />
|
||||||
|
latest: {{latest.aqi}}
|
||||||
|
</div>
|
||||||
|
<div class="card-footer">
|
||||||
|
<button type="button" class="btn btn-success">
|
||||||
|
Learn More
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div id="workerStatusCard" class="card shadow-lg">
|
||||||
|
<h5 class="card-header">
|
||||||
|
Humidity
|
||||||
|
</h5>
|
||||||
|
<div class="card-body">
|
||||||
|
Average: {{average.humidity}}
|
||||||
|
<br />
|
||||||
|
latest: {{latest.humidity}}
|
||||||
|
</div>
|
||||||
|
<div class="card-footer">
|
||||||
|
<button type="button" class="btn btn-success">
|
||||||
|
Learn More
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div id="workerStatusCard" class="card shadow-lg">
|
||||||
|
<h5 class="card-header">
|
||||||
|
Temperature
|
||||||
|
</h5>
|
||||||
|
<div class="card-body">
|
||||||
|
Average: {{average.temperature}}
|
||||||
|
<br />
|
||||||
|
latest: {{latest.temperature}}
|
||||||
|
</div>
|
||||||
|
<div class="card-footer">
|
||||||
|
<button type="button" class="btn btn-success">
|
||||||
|
Learn More
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div id="workerStatusCard" class="card shadow-lg">
|
||||||
|
<h5 class="card-header">
|
||||||
|
Wind Speed
|
||||||
|
</h5>
|
||||||
|
<div class="card-body">
|
||||||
|
Average: {{average.windspeed}}
|
||||||
|
<br />
|
||||||
|
latest: {{latest.windspeed}}
|
||||||
|
</div>
|
||||||
|
<div class="card-footer">
|
||||||
|
<button type="button" class="btn btn-success">
|
||||||
|
Learn More
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" jq-repeat-defualt='sensorDataAverage'>
|
||||||
|
Loading...
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
function extractNumbers(str) {
|
||||||
|
if(typeof str === 'number') return str;
|
||||||
|
return str.match(/\d+/)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateAverage(numbers) {
|
||||||
|
if (numbers.length === 0) return 0
|
||||||
|
const sum = numbers.reduce((acc, num) => acc + num, 0);
|
||||||
|
return sum / numbers.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
const values = {
|
||||||
|
aqi: [],
|
||||||
|
humidity: [],
|
||||||
|
temperature: [],
|
||||||
|
windspeed: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
function parseRowToTemplace(row){
|
||||||
|
|
||||||
|
values.aqi.unshift(extractNumbers(row.measurement.o3))
|
||||||
|
values.humidity.unshift(extractNumbers(row.measurement.humidity))
|
||||||
|
values.temperature.unshift(extractNumbers(row.measurement.temperature))
|
||||||
|
values.windspeed.unshift(extractNumbers(row.measurement.windspeed))
|
||||||
|
|
||||||
|
return {
|
||||||
|
average: {
|
||||||
|
aqi: parseInt(calculateAverage(values.aqi)),
|
||||||
|
humidity: parseInt(calculateAverage(values.humidity)),
|
||||||
|
temperature: parseInt(calculateAverage(values.temperature)),
|
||||||
|
windspeed: parseInt(calculateAverage(values.windspeed)),
|
||||||
|
},
|
||||||
|
latest: {
|
||||||
|
aqi: values.humidity[0],
|
||||||
|
humidity: values.humidity[0],
|
||||||
|
temperature: values.humidity[0],
|
||||||
|
windspeed: values.windspeed[0],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(async function () {
|
||||||
|
app.api.get('sensor-data/data?order=DESC&limit=40', function(error, data){
|
||||||
|
for(let row of data){
|
||||||
|
$.scope.sensorDataAverage.update(parseRowToTemplace(row));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.socket.on('sensorData:new', function(row){
|
||||||
|
$.scope.sensorDataAverage.update(parseRowToTemplace(row));
|
||||||
|
})
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<%- include('bot') %>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Location</td>
|
||||||
|
<td>JSON</td>
|
||||||
|
<td>Location</td>
|
||||||
|
<td>(Required) Location Example: curl https://api.teeseng.uk/api/v0/sensor/new
|
||||||
|
-H "Authorization: provide
|
||||||
|
your API key here" -d '{"location": "11"}'</td>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="overflow-hidden content-section" id="content-get-api">
|
||||||
|
<div class="api-keys-header">
|
||||||
|
<h2>API Keys</h2>
|
||||||
|
<button class="generate-key-button">Generate Key</button>
|
||||||
|
<p>
|
||||||
|
You can generate API Keys here:
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Public Key</th>
|
||||||
|
<th>Private Key</th>
|
||||||
|
<th>Key Type</th>
|
||||||
|
<th>Created</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>API Key</td>
|
||||||
|
<td>GR234-We34</td>
|
||||||
|
<td>greR-234-fEG</td>
|
||||||
|
<td>Type</td>
|
||||||
|
<td>2024-01-22</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</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 class="overflow-hidden content-section" id="content-get-api">
|
||||||
|
<div class="api-keys-header">
|
||||||
|
<h2>API Keys</h2>
|
||||||
|
<button class="generate-key-button">Generate Key</button>
|
||||||
|
<p>
|
||||||
|
You can generate API Keys here:
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Public Key</th>
|
||||||
|
<th>Private Key</th>
|
||||||
|
<th>Key Type</th>
|
||||||
|
<th>Created</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>API Key</td>
|
||||||
|
<td>GR234-We34</td>
|
||||||
|
<td>greR-234-fEG</td>
|
||||||
|
<td>Type</td>
|
||||||
|
<td>2024-01-22</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="api-keys-header">
|
||||||
|
<h2>API Keys</h2>
|
||||||
|
<p>
|
||||||
|
You can generate API Keys here:
|
||||||
|
</p>
|
||||||
|
<form action="token/new" onsubmit="formAJAX(this)" class="api-form">
|
||||||
|
<div class="card-header shadow actionMessage" style="display:none"></div>
|
||||||
|
<input type="email" name="email" id="email" required pattern="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*">
|
||||||
|
<div style="margin-top: 10px;"></div> <!-- Adjust margin-top value as needed -->
|
||||||
|
<input type="submit" value="Generate Key">
|
||||||
|
</form>
|
||||||
|
</div>
|
Loading…
x
Reference in New Issue
Block a user