https://github.com/cellajs/imado
File handling, optionally to be used in combination will CellaJS.
https://github.com/cellajs/imado
aws-lambda files images transformation tus-protocol uploading video
Last synced: about 1 year ago
JSON representation
File handling, optionally to be used in combination will CellaJS.
- Host: GitHub
- URL: https://github.com/cellajs/imado
- Owner: cellajs
- Created: 2023-12-20T12:27:17.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-11-06T14:42:27.000Z (over 1 year ago)
- Last Synced: 2025-04-20T12:17:17.765Z (about 1 year ago)
- Topics: aws-lambda, files, images, transformation, tus-protocol, uploading, video
- Language: TypeScript
- Homepage: https://imado.eu
- Size: 328 KB
- Stars: 5
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Imado (+ TUS + AWS Lambda + S3)
Imado is built as a configure-once solution for file handling with the TUS protocol, for public as well as for private files. It supports images and files such as PDF and DOCX and runs on AWS Lambda. Data - including cache - is stored on your own S3 bucket. Optionally it also supports videos.
This repo is a helper to use Imado and is currently being used by [CellaJS](https://github.com/cellajs/cella). The required AWS lambda repo is currently private.
[Contact us here](https://cellajs.com/contact) if you are interested in using it or email us at .
## Server
Wrap tus + s3-store and the Imado API to start uploading to your api.
```typescript
import { ImadoTus } from "imado";
import { env } from "env"; // or wherever you store your env variables
const tus = ImadoTus({
secret: env.TUS_UPLOAD_API_SECRET,
credentials: {
bucket: env.AWS_S3_UPLOAD_BUCKET,
region: env.AWS_S3_UPLOAD_REGION,
accessKeyId: env.AWS_S3_UPLOAD_ACCESS_KEY_ID,
secretAccessKey: env.AWS_S3_UPLOAD_SECRET_ACCESS_KEY,
},
});
tus.listen({
host: "0.0.0.0",
port: Number(env.TUS_PORT ?? "1080"),
});
```
## Signed (private) URLs
Generate signed URLs for your private CDN (if the url does not include the signUrl it will just pass through).
```typescript
import { ImadoUrl } from "imado";
import { env } from "env";
export const getImadoUrl = new ImadoUrl({
signUrl: env.PRIVATE_CDN_ROOT,
cloudfrontKeyId: env.AWS_CLOUDFRONT_KEY_ID,
cloudfrontPrivateKey: env.AWS_CLOUDFRONT_PRIVATE_KEY,
});
const thumbnailUrl = `${env.PRIVATE_CDN_ROOT}/thumbnail.jpg`;
const signedThumbnailUrl = getImadoUrl.generate(thumbnailUrl, {
width: 100,
format: "avif",
});
```
## What to do on your application
### Backend
- Create an endpoint with a JWT including a `public` boolean and `sub` in the payload. Recommended would also to define a `expiresIn` (exp). For example:
```typescript
const jwt = require("jsonwebtoken");
async function getUploadToken(ctx) {
const isPublic = ctx.req.query("public");
const user = ctx.get("user");
const token = jwt.sign(
{ sub: user.id, public: isPublic === "true" },
process.env.TUS_UPLOAD_API_SECRET
);
return ctx.json({
success: true,
data: token,
});
}
```
### Frontend
You would include something like [Uppy](https://uppy.io/) and uppy/tus.
```typescript
import Uppy from "@uppy/core";
import Tus from "@uppy/tus";
// Get the JWT from your server
const { token } = await (await fetch("/api/upload/token?public=true")).json();
// Convience method to read out JWT (base64) string
const readJwt = (token: string) => JSON.parse(atob(token.split(".")[1]));
// Read out JWT
const { public: isPublic, sub } = readJwt(token);
const uppy = new Uppy({
meta: {
public: isPublic,
},
})
.use(Tus, {
endpoint: "http://localhost:1080", // endpoint for tus
removeFingerprintOnSuccess: true,
headers: {
authorization: `Bearer ${token}`, // pass the JWT to tus
},
})
.on("complete", (result) => {
if (result.successful) {
const urls = result.successful.map((file) => {
const uploadKey = file.uploadURL.split("/").pop();
return new URL(`https://path_to_your_cdn.com/${sub}/${uploadKey}`);
});
// Do something with the urls!
}
});
```