implement file uploading
This commit is contained in:
parent
36a5df1665
commit
abdf5c2229
5 changed files with 128 additions and 15 deletions
3
asset-api/.gitignore
vendored
3
asset-api/.gitignore
vendored
|
@ -11,3 +11,6 @@
|
||||||
|
|
||||||
#!.yarn/cache
|
#!.yarn/cache
|
||||||
.pnp.*
|
.pnp.*
|
||||||
|
|
||||||
|
.keys
|
||||||
|
.assets
|
|
@ -1,10 +1,12 @@
|
||||||
import { readFile } from "node:fs/promises"
|
import { readFile } from "node:fs/promises"
|
||||||
import { readFileSync } from "node:fs";
|
import { createWriteStream, readFileSync, writeFileSync } from "node:fs";
|
||||||
import { createSign } from "node:crypto";
|
import { createSign, generateKeyPairSync, randomUUID } from "node:crypto";
|
||||||
import Fastify from "fastify";
|
import Fastify from "fastify";
|
||||||
|
import multipart from '@fastify/multipart'
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
import mime from "mime"
|
import mime from "mime"
|
||||||
import { assert } from "node:console";
|
import { promisify } from "node:util";
|
||||||
|
import { pipeline } from "node:stream";
|
||||||
|
|
||||||
const M2M_ALGORITHM = "RSA-SHA512"
|
const M2M_ALGORITHM = "RSA-SHA512"
|
||||||
const { private: M2M_PRIVATE_KEY, public: M2M_PUBLIC_KEY } = loadM2MKeys()
|
const { private: M2M_PRIVATE_KEY, public: M2M_PUBLIC_KEY } = loadM2MKeys()
|
||||||
|
@ -13,7 +15,7 @@ if (M2M_PRIVATE_KEY == null || M2M_PUBLIC_KEY == null) {
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
const ASSETS_FOLDER = "../.assets/"
|
const ASSETS_FOLDER = "./.assets/"
|
||||||
const ASSET_API_LANDING_MESSAGE = "asset-api v1.0.0"
|
const ASSET_API_LANDING_MESSAGE = "asset-api v1.0.0"
|
||||||
|
|
||||||
const IDENTITY_API_ENDPOINT = "http://localhost:3000"
|
const IDENTITY_API_ENDPOINT = "http://localhost:3000"
|
||||||
|
@ -22,6 +24,8 @@ const fastify = new Fastify({
|
||||||
logger: true,
|
logger: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
fastify.register(multipart)
|
||||||
|
|
||||||
fastify.get("/", async (request, reply) => {
|
fastify.get("/", async (request, reply) => {
|
||||||
return signString(ASSET_API_LANDING_MESSAGE)
|
return signString(ASSET_API_LANDING_MESSAGE)
|
||||||
})
|
})
|
||||||
|
@ -36,10 +40,25 @@ fastify.get("/crypto/algo", (request, reply) => {
|
||||||
|
|
||||||
fastify.put("/asset", {
|
fastify.put("/asset", {
|
||||||
async handler(request, reply) {
|
async handler(request, reply) {
|
||||||
let user = await userFromSessionKey(request.query.session_key)
|
await userFromSessionKey(request.query.session_key)
|
||||||
|
let file = await request.file()
|
||||||
|
|
||||||
// continue working onmthis
|
let id = randomUUID().toString()
|
||||||
console.log(typeof request.body)
|
let extension = mime.getExtension(file.mimetype) || ".bin"
|
||||||
|
let full_id = `${id}.${extension}`
|
||||||
|
|
||||||
|
let url = new URL(IDENTITY_API_ENDPOINT)
|
||||||
|
url.pathname = "/m2m/asset"
|
||||||
|
|
||||||
|
await fetch(url, {
|
||||||
|
method: "PUT",
|
||||||
|
body: signObject({
|
||||||
|
session_key: request.query.session_key,
|
||||||
|
asset_id: full_id,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
promisify(pipeline)(file.file, createWriteStream(`.assets/${full_id}`))
|
||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
query: {
|
query: {
|
||||||
|
@ -80,9 +99,30 @@ fastify.get("/asset", {
|
||||||
fastify.listen({ port: 3001 })
|
fastify.listen({ port: 3001 })
|
||||||
|
|
||||||
function loadM2MKeys() {
|
function loadM2MKeys() {
|
||||||
|
try {
|
||||||
return {
|
return {
|
||||||
private: readFileSync("../.keys/m2m-dev.pem").toString("ascii"),
|
private: readFileSync("./.keys/m2m.pem").toString("ascii"),
|
||||||
public: readFileSync("../.keys/m2m-dev.pub").toString("ascii"),
|
public: readFileSync("./.keys/m2m.pub").toString("ascii"),
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Generating M2M key pair!")
|
||||||
|
|
||||||
|
let { publicKey, privateKey } = generateKeyPairSync("rsa", {
|
||||||
|
modulusLength: 4096,
|
||||||
|
publicKeyEncoding: {
|
||||||
|
type: 'spki',
|
||||||
|
format: 'pem',
|
||||||
|
},
|
||||||
|
privateKeyEncoding: {
|
||||||
|
type: 'pkcs8',
|
||||||
|
format: 'pem',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
writeFileSync("./.keys/m2m.pem", privateKey)
|
||||||
|
writeFileSync("./.keys/m2m.pub", publicKey)
|
||||||
|
|
||||||
|
return loadM2MKeys()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +143,7 @@ async function userFromSessionKey(session_key) {
|
||||||
let res1 = await fetch(url, {
|
let res1 = await fetch(url, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: signObject({
|
body: signObject({
|
||||||
session_key: request.query.session_key,
|
session_key,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"packageManager": "yarn@4.3.0",
|
"packageManager": "yarn@4.3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@fastify/multipart": "^8.3.0",
|
||||||
"fastify": "^4.28.0",
|
"fastify": "^4.28.0",
|
||||||
"mime": "^4.0.3",
|
"mime": "^4.0.3",
|
||||||
"uuid": "^10.0.0"
|
"uuid": "^10.0.0"
|
||||||
|
|
|
@ -16,7 +16,21 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@fastify/error@npm:^3.3.0, @fastify/error@npm:^3.4.0":
|
"@fastify/busboy@npm:^2.1.0":
|
||||||
|
version: 2.1.1
|
||||||
|
resolution: "@fastify/busboy@npm:2.1.1"
|
||||||
|
checksum: 10c0/6f8027a8cba7f8f7b736718b013f5a38c0476eea67034c94a0d3c375e2b114366ad4419e6a6fa7ffc2ef9c6d3e0435d76dd584a7a1cbac23962fda7650b579e3
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@fastify/deepmerge@npm:^1.0.0":
|
||||||
|
version: 1.3.0
|
||||||
|
resolution: "@fastify/deepmerge@npm:1.3.0"
|
||||||
|
checksum: 10c0/8115ed7b891189ee4ebba554a105cb69111615bdb2961f8c58a80872fac9d7b74b2c6317d545a7d378325d094ce73a91fc9c5d7d6189476779cd5a5493cb1351
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@fastify/error@npm:^3.0.0, @fastify/error@npm:^3.3.0, @fastify/error@npm:^3.4.0":
|
||||||
version: 3.4.1
|
version: 3.4.1
|
||||||
resolution: "@fastify/error@npm:3.4.1"
|
resolution: "@fastify/error@npm:3.4.1"
|
||||||
checksum: 10c0/1f1a0faa8c86639afb6f4bd47a9cdc1f0f20ce0d6944340fbdec8218aaba91dc9cae9ed78e24e61bceb782a867efda2b9a6320091f00dcbb896d9c8a9bdf5f96
|
checksum: 10c0/1f1a0faa8c86639afb6f4bd47a9cdc1f0f20ce0d6944340fbdec8218aaba91dc9cae9ed78e24e61bceb782a867efda2b9a6320091f00dcbb896d9c8a9bdf5f96
|
||||||
|
@ -41,6 +55,20 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@fastify/multipart@npm:^8.3.0":
|
||||||
|
version: 8.3.0
|
||||||
|
resolution: "@fastify/multipart@npm:8.3.0"
|
||||||
|
dependencies:
|
||||||
|
"@fastify/busboy": "npm:^2.1.0"
|
||||||
|
"@fastify/deepmerge": "npm:^1.0.0"
|
||||||
|
"@fastify/error": "npm:^3.0.0"
|
||||||
|
fastify-plugin: "npm:^4.0.0"
|
||||||
|
secure-json-parse: "npm:^2.4.0"
|
||||||
|
stream-wormhole: "npm:^1.1.0"
|
||||||
|
checksum: 10c0/1021675af149435b1e585cfcaf8aba848c3799cbc213c18a0e3d74c6d64d21db27572a99295a8da5263f5562869452234dea2680e83e248456d97b560fb627eb
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"abort-controller@npm:^3.0.0":
|
"abort-controller@npm:^3.0.0":
|
||||||
version: 3.0.0
|
version: 3.0.0
|
||||||
resolution: "abort-controller@npm:3.0.0"
|
resolution: "abort-controller@npm:3.0.0"
|
||||||
|
@ -101,6 +129,7 @@ __metadata:
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "asset-api@workspace:."
|
resolution: "asset-api@workspace:."
|
||||||
dependencies:
|
dependencies:
|
||||||
|
"@fastify/multipart": "npm:^8.3.0"
|
||||||
fastify: "npm:^4.28.0"
|
fastify: "npm:^4.28.0"
|
||||||
mime: "npm:^4.0.3"
|
mime: "npm:^4.0.3"
|
||||||
uuid: "npm:^10.0.0"
|
uuid: "npm:^10.0.0"
|
||||||
|
@ -221,6 +250,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"fastify-plugin@npm:^4.0.0":
|
||||||
|
version: 4.5.1
|
||||||
|
resolution: "fastify-plugin@npm:4.5.1"
|
||||||
|
checksum: 10c0/f58f79cd9d3c88fd7f79a3270276c6339fc57bbe72ef14d20b73779193c404e317ac18e8eae2c5071b3909ebee45d7eb6871da4e65464ac64ed0d9746b4e9b9f
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"fastify@npm:^4.28.0":
|
"fastify@npm:^4.28.0":
|
||||||
version: 4.28.0
|
version: 4.28.0
|
||||||
resolution: "fastify@npm:4.28.0"
|
resolution: "fastify@npm:4.28.0"
|
||||||
|
@ -476,7 +512,7 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"secure-json-parse@npm:^2.7.0":
|
"secure-json-parse@npm:^2.4.0, secure-json-parse@npm:^2.7.0":
|
||||||
version: 2.7.0
|
version: 2.7.0
|
||||||
resolution: "secure-json-parse@npm:2.7.0"
|
resolution: "secure-json-parse@npm:2.7.0"
|
||||||
checksum: 10c0/f57eb6a44a38a3eeaf3548228585d769d788f59007454214fab9ed7f01fbf2e0f1929111da6db28cf0bcc1a2e89db5219a59e83eeaec3a54e413a0197ce879e4
|
checksum: 10c0/f57eb6a44a38a3eeaf3548228585d769d788f59007454214fab9ed7f01fbf2e0f1929111da6db28cf0bcc1a2e89db5219a59e83eeaec3a54e413a0197ce879e4
|
||||||
|
@ -515,6 +551,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"stream-wormhole@npm:^1.1.0":
|
||||||
|
version: 1.1.0
|
||||||
|
resolution: "stream-wormhole@npm:1.1.0"
|
||||||
|
checksum: 10c0/50800bcc919c01085b0bafa175c61a0c0bec27987dcc20aec92f8125bdc8b191102a030e114760d2ac86265eea65627d0145eea3adb8cb4453b3295e4468661a
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"string_decoder@npm:^1.3.0":
|
"string_decoder@npm:^1.3.0":
|
||||||
version: 1.3.0
|
version: 1.3.0
|
||||||
resolution: "string_decoder@npm:1.3.0"
|
resolution: "string_decoder@npm:1.3.0"
|
||||||
|
|
|
@ -11,8 +11,31 @@ const JWT_SECRET = new TextEncoder().encode(
|
||||||
const JWT_ALG = 'HS256'
|
const JWT_ALG = 'HS256'
|
||||||
|
|
||||||
const ASSET_API_ENDPOINT = "http://localhost:3001/"
|
const ASSET_API_ENDPOINT = "http://localhost:3001/"
|
||||||
const ASSET_API_PUBKEY = await loadAssetPubkey()
|
let ASSET_API_PUBKEY = await loadAssetPubkey()
|
||||||
const ASSET_API_ALGORITHM = await loadAssetAlgo()
|
let ASSET_API_ALGORITHM = await loadAssetAlgo()
|
||||||
|
|
||||||
|
setInterval(async () => {
|
||||||
|
try {
|
||||||
|
let pubkey = await loadAssetPubkey()
|
||||||
|
let algo = await loadAssetAlgo()
|
||||||
|
|
||||||
|
if (pubkey != null && algo != null) {
|
||||||
|
if (ASSET_API_PUBKEY !== pubkey) {
|
||||||
|
console.warn("The M2M public key has changed!")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ASSET_API_ALGORITHM !== algo) {
|
||||||
|
console.warn("The M2M algorith has changed!")
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSET_API_PUBKEY = pubkey
|
||||||
|
ASSET_API_ALGORITHM = algo
|
||||||
|
console.debug("Successfully updated the M2M public key and algorithm")
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Failed to update the M2M public key", e)
|
||||||
|
}
|
||||||
|
}, 60 * 1000)
|
||||||
|
|
||||||
let session_keys = {
|
let session_keys = {
|
||||||
'uid:005d6417-a23c-48bd-b348-eafeae649b94': 'e381ba8c-e18a-4bca-afce-b212b37bc26b',
|
'uid:005d6417-a23c-48bd-b348-eafeae649b94': 'e381ba8c-e18a-4bca-afce-b212b37bc26b',
|
||||||
|
@ -22,6 +45,7 @@ let session_keys = {
|
||||||
let users = {
|
let users = {
|
||||||
'jane@identity.net': {
|
'jane@identity.net': {
|
||||||
uid: '005d6417-a23c-48bd-b348-eafeae649b94',
|
uid: '005d6417-a23c-48bd-b348-eafeae649b94',
|
||||||
|
email: 'jane@identity.net',
|
||||||
password: '12345678901234567890',
|
password: '12345678901234567890',
|
||||||
name: 'Jane Doe',
|
name: 'Jane Doe',
|
||||||
assets: ["f9d040d6-598c-4483-952f-08e7d35d5420.jpg"],
|
assets: ["f9d040d6-598c-4483-952f-08e7d35d5420.jpg"],
|
||||||
|
@ -50,6 +74,7 @@ fastify.put("/m2m/asset", {
|
||||||
assert(user.length === 1)
|
assert(user.length === 1)
|
||||||
|
|
||||||
users[user[0].email].assets.push(body.asset_id)
|
users[user[0].email].assets.push(body.asset_id)
|
||||||
|
console.log(users[user[0].email].assets)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -154,6 +179,7 @@ fastify.post('/auth/register', {
|
||||||
if (users[request.body.email] == null) {
|
if (users[request.body.email] == null) {
|
||||||
users[request.body.email] = {
|
users[request.body.email] = {
|
||||||
uid: uuidv4(),
|
uid: uuidv4(),
|
||||||
|
email: request.body.email,
|
||||||
password: request.body.password,
|
password: request.body.password,
|
||||||
name: request.body.name,
|
name: request.body.name,
|
||||||
assets: [],
|
assets: [],
|
||||||
|
|
Loading…
Reference in a new issue