aboutsummaryrefslogtreecommitdiff
path: root/api
diff options
context:
space:
mode:
authorParker <contact@pkrm.dev>2024-11-10 23:17:10 -0600
committerParker <contact@pkrm.dev>2024-11-10 23:17:10 -0600
commit05666369a2e9bb23f9471b11009963eccc838bf6 (patch)
tree11a63a514d4655932ae6f8d3fcb2589d31a53150 /api
parentcd237804149bb098868048ccc001d3a6db986565 (diff)
Some clean-up
Diffstat (limited to 'api')
-rw-r--r--api/static/js/api.js26
-rw-r--r--api/templates/dashboard.html160
-rw-r--r--api/templates/login.html105
-rw-r--r--api/templates/signup.html112
4 files changed, 0 insertions, 403 deletions
diff --git a/api/static/js/api.js b/api/static/js/api.js
deleted file mode 100644
index 243edf7..0000000
--- a/api/static/js/api.js
+++ /dev/null
@@ -1,26 +0,0 @@
-// Description: This file contains functions to access the API with JWT authentication.
-
-/**
- * Accept an API endpoint, method, and body to send to the API.
- * - If successful, return the response
- * - If not, return false
- * @param {*} endpoint API endpoint
- * @param {*} method String (GET, POST, PUT, DELETE)
- * @param {*} body Data to send to the API
- * @returns response.json or false
- */
-async function accessAPI(endpoint, method, body) {
- let response = await fetch(`/api${endpoint}`, {
- method: method,
- body: body,
- });
-
- if (response.ok) {
- let data = await response.json();
- data = await data;
- return data;
-
- }
-
- return false;
-} \ No newline at end of file
diff --git a/api/templates/dashboard.html b/api/templates/dashboard.html
deleted file mode 100644
index 25372bd..0000000
--- a/api/templates/dashboard.html
+++ /dev/null
@@ -1,160 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>LinkLogger | Dashboard</title>
-
- <link rel="stylesheet" href="/static/css/dashboard.css">
- <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
- <script src="/static/js/jwt.js"></script>
-</head>
-<body>
- <div>
- <!-- Create a table with 4 columns with a total of 1000px width -->
- <table>
- <tr style="border: 2px solid #ccc;">
- <th>Link</th>
- <th>Visits</th>
- <th>Redirect</th>
- <th>Expire Date</th>
- </tr>
- </table>
- </div>
-</body>
-</html>
-<script>
- function createRow(index, link, logs) {
- // Create the sub-table with the logs
- let subTable = `
- <table>
- <tr>
- <th>ID</th>
- <th>Timestamp</th>
- <th>IP</th>
- <th>Location</th>
- <th colspan="2">ISP</th>
- </tr>
- `;
- // Loop through the logs and create a row for each one
- logs.forEach((log, index) => {
- let logTimestamp = new Date(log.timestamp).toLocaleString('en-US', {
- year: 'numeric',
- month: '2-digit',
- day: '2-digit',
- hour: '2-digit',
- minute: '2-digit',
- second: '2-digit',
- hour12: false
- }).replace(',', '');
-
- let row = `
- <tr id="${log.id}-log">
- <td>${logs.length - index}</td>
- <td>${logTimestamp}</td>
- <td>${log.ip}</td>
- <td>${log.location}</td>
- <td>${log.isp}</td>
- <td><i class="fa-solid fa-trash" id="${log.id}/${link.link}""></i></td>
- </tr>
- `;
- subTable += row;
- });
- subTable += '</table>';
-
- // Convert the link expire timestamp to a readable date
- let date = new Date(link.expire_date);
- let expireDate = date.toLocaleTimeString('en-US', {
- month: 'short',
- day: 'numeric',
- year: 'numeric',
- hour: '2-digit',
- minute: '2-digit',
- second: '2-digit',
- hour12: false
- });
-
- // Create the HTML for the row with sub-table
- let row = `
- <tr class="link-table-row">
- <td>
- <button class="link-button" id="${index}">${link.link}</button>
- </td>
- <td>${logs.length}</td>
- <td>${link.redirect_link}</td>
- <td>${expireDate}</td>
- </tr>
- <tr class="log-table-row" id="${index}-logTR" style="display: none;">
- <td colspan="6">
- ${subTable}
- </td>
- </tr>
- `;
- return row;
- }
-
-
-
- async function getData() {
- const links = await accessAPI(`/links`, 'GET')
- if (!links) {
- throw new Error('Failed to fetch links');
- }
- // Links is an Array of objects with the link data
- // Loop through the links and create a row for each one
- // Do not use async because then the order or data in the
- // table will change from time to time
- for (let i = 0; i < links.length; i++) {
- let link = links[i];
- let logs = await accessAPI(`/links/${link.link}/logs`, 'GET')
- if (!logs) {
- throw new Error('Failed to fetch logs');
- }
- let row = createRow(i, link, logs);
- document.querySelector('table').innerHTML += row;
- }
- }
-
- // hideLogRows to all log-table-rows
- function hideLogRows() {
- let logTRs = document.querySelectorAll('.log-table-row');
- logTRs.forEach(row => {
- row.style.display = 'none';
- });
- }
-
- // Add event listener to all link buttons
- document.addEventListener('click', (event) => {
- if (event.target.classList.contains('link-button')) {
- let id = event.target.id;
- let logTR = document.getElementById(`${id}-logTR`);
- if (logTR.style.display === 'none') {
- // Hide any open log tables
- hideLogRows();
- logTR.style.display = 'table-row';
- } else {
- logTR.style.display = 'none';
- }
- }
- });
-
- // Add an event listen to all trash bins
- document.addEventListener('click', (event) => {
- if (event.target.classList.contains('fa-trash')) {
- // Confirm the user wants to delete the log
- let confirmDelete = confirm('Are you sure you want to delete this log?');
- if (confirmDelete) {
- let id = event.target.id;
- let link = id.split('/')[1];
- let logId = id.split('/')[0];
- fetch(`/api/links/${link}/logs/${logId}`, {
- method: 'DELETE'
- });
- let logRow = document.getElementById(`${logId}-log`)
- logRow.remove();
- }
- }
- });
-
- getData();
-</script> \ No newline at end of file
diff --git a/api/templates/login.html b/api/templates/login.html
deleted file mode 100644
index 8e59481..0000000
--- a/api/templates/login.html
+++ /dev/null
@@ -1,105 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>LinkLogger | Login</title>
-</head>
-<body>
- <div>
- <p id="error">Incorrect username/password. Please try again.</p>
- <form action="/login" method="POST">
- <input type="text" name="username" placeholder="Username" required>
- <input type="password" name="password" placeholder="Password" required>
- <button type="submit">Login</button>
- </form>
- <hr>
- <p>Don't have an account? <a href="/signup">Create one now</a></p>
- </div>
-</body>
-</html>
-
-<style>
- body {
- margin: 0;
- padding: 0;
- font-family: Arial, sans-serif;
- background-color: #2c3338;
- }
-
- div {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- text-align: center;
- }
-
- input {
- display: block;
- margin: 10px auto;
- width: 300px;
- border-radius: 5px;
- padding: 15px;
- color: #ccc;
- background-color: #3b4148;
- border: none;
- font-size: 17px;
- }
-
- button {
- display: block;
- margin: 10px auto;
- width: 100%;
- border-radius: 5px;
- padding: 15px;
- color: #ccc;
- background-color: #415eac;
- border: none;
- font-size: 17px;
- cursor: pointer;
- }
-
- hr {
- color: #606468;
- }
-
- p {
- color: #606468;
- }
-
- #error {
- font-size: 15px;
- color: #f55757;
- display: none;
- }
-
- a {
- color: #ccc;
- text-decoration: none;
- }
-
- a:hover {
- text-decoration: underline;
- }
-</style>
-
-<script>
- document.querySelector('form').addEventListener('submit', async function(event) {
- // Prevent default form submission
- event.preventDefault();
-
- const formData = new FormData(this);
- // Send POST request to /token containing form data
- const response = await fetch('/api/auth/token', {
- method: 'POST',
- body: formData
- });
-
- if (response.status != 200) {
- document.getElementById('error').style.display = 'block';
- } else {
- window.location.href = '/dashboard';
- }
- });
-</script> \ No newline at end of file
diff --git a/api/templates/signup.html b/api/templates/signup.html
deleted file mode 100644
index 32962b7..0000000
--- a/api/templates/signup.html
+++ /dev/null
@@ -1,112 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>LinkLogger | Signup</title>
-</head>
-<body>
- <div>
- <p id="error"></p>
- <form action="/signup" method="POST">
- <input type="text" name="username" placeholder="Username" required>
- <input type="password" name="password" placeholder="Password" required>
- <button type="submit">Signup</button>
- </form>
- <hr>
- <p>Already have an account? <a href="/login">Log in now</a></p>
- <p>Passwords must be at least 8 characters long and contain a number, special character, and uppercase character.</p>
- </div>
-</body>
-</html>
-
-<style>
- body {
- margin: 0;
- padding: 0;
- font-family: Arial, sans-serif;
- background-color: #2c3338;
- }
-
- div {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- text-align: center;
- max-width: 330px;
- }
-
- input {
- display: block;
- margin: 10px auto;
- width: 300px;
- border-radius: 5px;
- padding: 15px;
- color: #ccc;
- background-color: #3b4148;
- border: none;
- font-size: 17px;
- }
-
- button {
- display: block;
- margin: 10px auto;
- width: 100%;
- border-radius: 5px;
- padding: 15px;
- color: #ccc;
- background-color: #415eac;
- border: none;
- font-size: 17px;
- cursor: pointer;
- }
-
- hr {
- color: #606468;
- }
-
- p {
- color: #606468;
- }
-
- #error {
- font-size: 15px;
- color: #f55757;
- display: none;
- }
-
- a {
- color: #ccc;
- text-decoration: none;
- }
-
- a:hover {
- text-decoration: underline;
- }
-</style>
-
-<script>
- document.querySelector('form').addEventListener('submit', async function(event) {
- // Prevent default form submission
- event.preventDefault();
-
- // Get form data
- const formData = new FormData(this);
-
- // Send POST request
- const response = await fetch('/api/users/register', {
- method: 'POST',
- body: formData
- });
-
- if (response.status != 200) {
- const data = await response.json()
-
- document.getElementById('error').style.display = 'block';
- document.getElementById('error').innerText = data.detail;
- } else {
- window.location.href = '/dashboard';
- }
- });
-</script> \ No newline at end of file