start some documentation work
This commit is contained in:
parent
a42eeeda90
commit
1e23bd879b
8 changed files with 8857 additions and 11052 deletions
53
README.md
53
README.md
|
@ -1,32 +1,37 @@
|
||||||
# Embedder
|
# Embedder 🖼️
|
||||||
|
|
||||||
A media host specialized in good looking embeds for services like Discord. No file size limits. No compression.
|
A media host specialized in producing visually appealing embeds for services like Discord. Enjoy limitless file sizes and no compression.
|
||||||
|
|
||||||
<img src="readmegif.gif">
|

|
||||||
|
|
||||||
Upcoming Features:
|
## 🚀 Upcoming Features
|
||||||
* Guest user accounts
|
|
||||||
* MariaDB/SQL support (uses sqlite for now)
|
|
||||||
|
|
||||||
Potential:
|
- 📊 MariaDB/SQL support (currently uses SQLite)
|
||||||
* IPFS
|
- 🔗 Redundancy & Sync: Enhance reliability and enable synchronization across nodes.
|
||||||
|
|
||||||
## Run
|
## 🌐 Potential Features
|
||||||
|
|
||||||
Source:
|
- 🛰️ IPFS Integration
|
||||||
```Bash
|
|
||||||
|
## 🔧 How to Run
|
||||||
|
|
||||||
|
### Using Source
|
||||||
|
|
||||||
|
```bash
|
||||||
$ export EBPASS=changeme
|
$ export EBPASS=changeme
|
||||||
$ export EBPORT=3000
|
$ export EBPORT=3000
|
||||||
$ export EBAPI_KEY=changeme #ShareX support
|
$ export EBAPI_KEY=changeme # For ShareX support
|
||||||
|
|
||||||
$ npm install
|
$ npm install
|
||||||
$ npm start
|
$ npm start
|
||||||
```
|
```
|
||||||
Default username is admin with the password being whatever EBPASS is
|
**Note**: Default username is `admin` with the password being whatever `EBPASS` is set to.
|
||||||
|
|
||||||
ShareX support is enabled at "/upload", requires auth with key, expire key is in days
|
### ShareX Support
|
||||||
JSON
|
|
||||||
```
|
Enabled at `/upload`. Requires authentication with key. `expire` key specifies duration in days.
|
||||||
|
|
||||||
|
```json
|
||||||
{
|
{
|
||||||
"Version": "14.1.0",
|
"Version": "14.1.0",
|
||||||
"Name": "embedder",
|
"Name": "embedder",
|
||||||
|
@ -49,13 +54,15 @@ JSON
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Docker Config
|
### Using Docker
|
||||||
```
|
|
||||||
|
```bash
|
||||||
docker run -d -p "3000:3000" -e EBPORT=3000 -e EBPASS=changeme -e EBAPI_KEY=changeme ghcr.io/waveringana/embedder:1.7.2
|
docker run -d -p "3000:3000" -e EBPORT=3000 -e EBPASS=changeme -e EBAPI_KEY=changeme ghcr.io/waveringana/embedder:1.7.2
|
||||||
```
|
```
|
||||||
|
|
||||||
Docker Compose
|
### Docker Compose
|
||||||
```
|
|
||||||
|
```yaml
|
||||||
version: '3.3'
|
version: '3.3'
|
||||||
services:
|
services:
|
||||||
embedder:
|
embedder:
|
||||||
|
@ -68,9 +75,9 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- ./db:/var/db
|
- ./db:/var/db
|
||||||
- ./uploads:/uploads
|
- ./uploads:/uploads
|
||||||
image: ghcr.io/waveringana/embedder:1.7.2
|
image: ghcr.io/waveringana/embedder:1.9.1
|
||||||
```
|
```
|
||||||
|
|
||||||
## License
|
## 📜 License
|
||||||
|
|
||||||
[The Unlicense](https://opensource.org/licenses/unlicense)
|
Distributed under [The Unlicense](https://opensource.org/licenses/unlicense).
|
||||||
|
|
|
@ -7,8 +7,8 @@ mkdirp.sync("./var/db");
|
||||||
|
|
||||||
export const db = new sqlite3.Database("./var/db/media.db");
|
export const db = new sqlite3.Database("./var/db/media.db");
|
||||||
|
|
||||||
|
/**Create the database schema for the embedders app*/
|
||||||
export function createDatabase(version: number){
|
export function createDatabase(version: number){
|
||||||
// create the database schema for the embedders app
|
|
||||||
console.log("Creating database");
|
console.log("Creating database");
|
||||||
|
|
||||||
db.run("CREATE TABLE IF NOT EXISTS users ( \
|
db.run("CREATE TABLE IF NOT EXISTS users ( \
|
||||||
|
@ -46,6 +46,27 @@ export function updateDatabase(oldVersion: number, newVersion: number){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Inserts into the media table */
|
||||||
|
export function insertToDB (filename: string, expireDate: Date, username: string) {
|
||||||
|
const params: MediaParams = [
|
||||||
|
filename,
|
||||||
|
expireDate,
|
||||||
|
username
|
||||||
|
];
|
||||||
|
|
||||||
|
db.run("INSERT INTO media (path, expire, username) VALUES (?, ?, ?)", params, function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
console.log(`Uploaded ${filename} to database`);
|
||||||
|
if (expireDate == null)
|
||||||
|
console.log("It will not expire");
|
||||||
|
else if (expireDate != null || expireDate != undefined)
|
||||||
|
console.log(`It will expire on ${expireDate}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**Searches the database and returns images with partial or exact keysearches */
|
/**Searches the database and returns images with partial or exact keysearches */
|
||||||
export function searchImages(imagename: string, partial: boolean) {
|
export function searchImages(imagename: string, partial: boolean) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
@ -75,7 +96,7 @@ export function createUser(username: string, password: string) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Selects a path for a file given ID */
|
/**Selects the path for a file given ID */
|
||||||
export function getPath(id: number | string) {
|
export function getPath(id: number | string) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const query = "SELECT path FROM media WHERE id = ?";
|
const query = "SELECT path FROM media WHERE id = ?";
|
||||||
|
|
|
@ -10,7 +10,7 @@ import fs from "fs";
|
||||||
import process from "process";
|
import process from "process";
|
||||||
|
|
||||||
import {extension, videoExtensions, imageExtensions} from "./lib";
|
import {extension, videoExtensions, imageExtensions} from "./lib";
|
||||||
import {db, MediaParams} from "./db";
|
import {db, MediaParams, insertToDB} from "./db";
|
||||||
|
|
||||||
export const checkAuth: Middleware = (req, res, next) => {
|
export const checkAuth: Middleware = (req, res, next) => {
|
||||||
if (!req.user) {
|
if (!req.user) {
|
||||||
|
@ -158,31 +158,10 @@ export const handleUpload: Middleware = (req, res, next) => {
|
||||||
|
|
||||||
if (files instanceof Array) {
|
if (files instanceof Array) {
|
||||||
for (const file in files) {
|
for (const file in files) {
|
||||||
insertToDB(files[file].filename, expireDate, username, next);
|
insertToDB(files[file].filename, expireDate, username);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
insertToDB(files.filename, expireDate, username, next);
|
insertToDB(files.filename, expireDate, username);
|
||||||
|
|
||||||
next();
|
next();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**Inserts into media database */
|
|
||||||
function insertToDB (filename: string, expireDate: Date, username: string, next: NextFunction) {
|
|
||||||
const params: MediaParams = [
|
|
||||||
filename,
|
|
||||||
expireDate,
|
|
||||||
username
|
|
||||||
];
|
|
||||||
|
|
||||||
db.run("INSERT INTO media (path, expire, username) VALUES (?, ?, ?)", params, function (err) {
|
|
||||||
if (err) {
|
|
||||||
console.log(err);
|
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
console.log(`Uploaded ${filename} to database`);
|
|
||||||
if (expireDate == null)
|
|
||||||
console.log("It will not expire");
|
|
||||||
else if (expireDate != null || expireDate != undefined)
|
|
||||||
console.log(`It will expire on ${expireDate}`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
103
documentation/database.md
Normal file
103
documentation/database.md
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
# Database Documentation for Embedder
|
||||||
|
|
||||||
|
Embedder utilizes **SQLite3** to manage its user system and store metadata for uploaded files.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Databases:
|
||||||
|
|
||||||
|
### `media.db`
|
||||||
|
- **Description**: Manages the user system and image metadata.
|
||||||
|
|
||||||
|
### `session.db`
|
||||||
|
- **Description**: Handles login session data to keep users logged in over time.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tables:
|
||||||
|
|
||||||
|
### Media Table
|
||||||
|
|
||||||
|
#### TypeScript Interface: `MediaRow`
|
||||||
|
|
||||||
|
- **Description**: Represents a row in the media table.
|
||||||
|
- **Fields**:
|
||||||
|
- `id`: Optional number or string
|
||||||
|
- `path`: String
|
||||||
|
- `expire`: Date object
|
||||||
|
- `username`: Optional string
|
||||||
|
|
||||||
|
#### SQL Structure
|
||||||
|
|
||||||
|
- `id`: INTEGER
|
||||||
|
- `path`: TEXT
|
||||||
|
- `expire`: INTEGER
|
||||||
|
- `username`: TEXT
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### User Table
|
||||||
|
|
||||||
|
#### TypeScript Interface: `UserRow`
|
||||||
|
|
||||||
|
- **Description**: Represents a row in the user table.
|
||||||
|
- **Fields**:
|
||||||
|
- `id`: Optional number
|
||||||
|
- `username`: String
|
||||||
|
- `hashed_password`: Any
|
||||||
|
- `salt`: Any
|
||||||
|
|
||||||
|
#### SQL Structure
|
||||||
|
|
||||||
|
- `id`: INTEGER
|
||||||
|
- `username`: TEXT
|
||||||
|
- `hashed_password`: BLOB
|
||||||
|
- `expire`: INTEGER
|
||||||
|
- `salt`: BLOB
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Database Interactions (`lib/db.ts`)
|
||||||
|
|
||||||
|
### `createDatabase(version: number)`
|
||||||
|
|
||||||
|
- **Description**: Initializes the database schema.
|
||||||
|
- **Parameters**:
|
||||||
|
- `version`: Number indicating the version of the database schema.
|
||||||
|
|
||||||
|
### `createUser(username: string, password: string)`
|
||||||
|
|
||||||
|
- **Description**: Inserts a new user record into the user table.
|
||||||
|
- **Parameters**:
|
||||||
|
- `username`: String representing the user's name.
|
||||||
|
- `password`: String representing the user's password.
|
||||||
|
|
||||||
|
### `insertToDB(filename: string, expireDate: Date, username: string)`
|
||||||
|
|
||||||
|
- **Description**: Adds a new media record into the media table.
|
||||||
|
- **Parameters**:
|
||||||
|
- `filename`: String representing the filename of the uploaded media.
|
||||||
|
- `expireDate`: Date object indicating when the media should expire.
|
||||||
|
- `username`: String representing the user's name.
|
||||||
|
|
||||||
|
### `getPath(id: number | string)`
|
||||||
|
|
||||||
|
- **Description**: Retrieves the path for a specific file using its ID.
|
||||||
|
- **Parameters**:
|
||||||
|
- `id`: Number or string representing the file's ID.
|
||||||
|
|
||||||
|
### `deleteId(database: string, id: number | string)`
|
||||||
|
|
||||||
|
- **Description**: Removes a record from the database.
|
||||||
|
- **Parameters**:
|
||||||
|
- `database`: String representing the name of the database.
|
||||||
|
- `id`: Number or string representing the ID of the record to be removed.
|
||||||
|
|
||||||
|
### `expire(database: string, column: string, expiration: number)`
|
||||||
|
|
||||||
|
- **Description**: Sets an expiration date for a particular database row.
|
||||||
|
- **Parameters**:
|
||||||
|
- `database`: String representing the name of the database.
|
||||||
|
- `column`: String representing the name of the column in which the date should be set.
|
||||||
|
- `expiration`: Number representing the Unix timestamp when the record should expire.
|
||||||
|
|
60
documentation/middleware.md
Normal file
60
documentation/middleware.md
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
# Express Middleware Documentation for Embedder
|
||||||
|
|
||||||
|
Embedder employs a series of middleware functions to facilitate operations such as user authentication, media conversions, and handling uploaded files.
|
||||||
|
|
||||||
|
## Middleware Functions
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `checkAuth()`
|
||||||
|
- **Description**: Ensures the user is authenticated.
|
||||||
|
- **Parameters**:
|
||||||
|
- `req`: Express request object
|
||||||
|
- `res`: Express response object
|
||||||
|
- `next`: Callback to the next middleware function
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `checkSharexAuth()`
|
||||||
|
- **Description**: Validates the ShareX authentication key provided in the headers.
|
||||||
|
- **Parameters**:
|
||||||
|
- `req`: Express request object
|
||||||
|
- `res`: Express response object
|
||||||
|
- `next`: Callback to the next middleware function
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `createEmbedData()`
|
||||||
|
- **Description**: Generates oEmbed metadata for embeds and saves them as JSON files.
|
||||||
|
- **Parameters**:
|
||||||
|
- `req`: Express request object
|
||||||
|
- `res`: Express response object
|
||||||
|
- `next`: Callback to the next middleware function
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `convert()`
|
||||||
|
- **Description**: Converts media files between video and GIF formats using ffmpeg.
|
||||||
|
- **Parameters**:
|
||||||
|
- `req`: Express request object
|
||||||
|
- `res`: Express response object
|
||||||
|
- `next`: Callback to the next middleware function
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `convertTo720p()`
|
||||||
|
- **Description**: Converts the uploaded video to a 720p resolution to reduce file size.
|
||||||
|
- **Parameters**:
|
||||||
|
- `req`: Express request object
|
||||||
|
- `res`: Express response object
|
||||||
|
- `next`: Callback to the next middleware function
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `handleUpload()`
|
||||||
|
- **Description**: Manages the uploaded files and records their metadata into the database.
|
||||||
|
- **Parameters**:
|
||||||
|
- `req`: Express request object
|
||||||
|
- `res`: Express response object
|
||||||
|
- `next`: Callback to the next middleware function
|
||||||
|
|
Before Width: | Height: | Size: 2.3 MiB After Width: | Height: | Size: 2.3 MiB |
30
documentation/routing.md
Normal file
30
documentation/routing.md
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# Routing
|
||||||
|
|
||||||
|
Embedder utilizes **Express** for routing and serving the app. Templating is currently with **EJS**, but there's a potential future migration to **React**. **Passport** is employed for authentication.
|
||||||
|
|
||||||
|
## Routes:
|
||||||
|
|
||||||
|
- **/** ([index.ts](../app/routes/index.ts))
|
||||||
|
- `GET`:
|
||||||
|
- Unauthenticated: Serve `home.ejs`
|
||||||
|
- Authenticated: Serve `index.ejs`
|
||||||
|
- `POST`: Redirect to `/`
|
||||||
|
|
||||||
|
- **/login** ([auth.ts](../app/routes/auth.ts))
|
||||||
|
- `GET`: Serve `login.ejs`
|
||||||
|
- `POST` to `/login/password`:
|
||||||
|
- Success: Redirect to `/`
|
||||||
|
- Failure: Redirect to `/login`
|
||||||
|
|
||||||
|
- **/logout** ([auth.ts](../app/routes/auth.ts))
|
||||||
|
- `POST`: Redirect to `/`
|
||||||
|
|
||||||
|
- **/gifv** ([index.ts](../app/routes/index.ts))
|
||||||
|
- `GET`: Serve `gifv.ejs`
|
||||||
|
- `POST` to `/adduser`: Redirect to `/`
|
||||||
|
|
||||||
|
- **/adduser** ([adduser.ts](../app/routes/adduser.ts))
|
||||||
|
- `GET`: Serve `adduser.ejs`
|
||||||
|
|
||||||
|
- **/sharex** ([index.ts](../app/routes/index.ts))
|
||||||
|
- `POST`: Response is text containing path to uploaded file
|
19611
package-lock.json
generated
19611
package-lock.json
generated
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue