2024-06-16 10:53:12 +00:00
|
|
|
import { readFile } from "node:fs/promises"
|
|
|
|
import { readFileSync } from "node:fs";
|
2024-06-16 10:18:19 +00:00
|
|
|
import { createSign } from "node:crypto";
|
2024-06-15 19:58:23 +00:00
|
|
|
import Fastify from "fastify";
|
2024-06-16 10:53:12 +00:00
|
|
|
import { join } from "node:path";
|
|
|
|
import mime from "mime"
|
|
|
|
import { assert } from "node:console";
|
2024-06-15 19:58:23 +00:00
|
|
|
|
2024-06-16 10:18:19 +00:00
|
|
|
const M2M_ALGORITHM = "RSA-SHA512"
|
2024-06-16 10:53:12 +00:00
|
|
|
const { private: M2M_PRIVATE_KEY, public: M2M_PUBLIC_KEY } = loadM2MKeys()
|
|
|
|
if (M2M_PRIVATE_KEY == null || M2M_PUBLIC_KEY == null) {
|
|
|
|
console.error("Couldn't load keys")
|
|
|
|
process.exit(1)
|
|
|
|
}
|
2024-06-16 10:18:19 +00:00
|
|
|
|
2024-06-16 10:53:12 +00:00
|
|
|
const ASSETS_FOLDER = "../.assets/"
|
2024-06-15 19:58:23 +00:00
|
|
|
const ASSET_API_LANDING_MESSAGE = "asset-api v1.0.0"
|
|
|
|
|
2024-06-16 10:18:19 +00:00
|
|
|
const IDENTITY_API_ENDPOINT = "http://localhost:3000"
|
|
|
|
|
2024-06-15 19:58:23 +00:00
|
|
|
const fastify = new Fastify({
|
|
|
|
logger: true,
|
|
|
|
})
|
|
|
|
|
|
|
|
fastify.get("/", async (request, reply) => {
|
2024-06-16 10:18:19 +00:00
|
|
|
return signString(ASSET_API_LANDING_MESSAGE)
|
|
|
|
})
|
|
|
|
|
|
|
|
fastify.get("/crypto/cert", async (request, reply) => {
|
|
|
|
return M2M_PUBLIC_KEY
|
|
|
|
})
|
|
|
|
|
|
|
|
fastify.get("/crypto/algo", (request, reply) => {
|
|
|
|
return M2M_ALGORITHM
|
2024-06-15 19:58:23 +00:00
|
|
|
})
|
|
|
|
|
2024-06-16 10:53:12 +00:00
|
|
|
fastify.put("/asset", {
|
|
|
|
async handler(request, reply) {
|
|
|
|
let user = await userFromSessionKey(request.query.session_key)
|
|
|
|
|
|
|
|
// continue working onmthis
|
|
|
|
console.log(typeof request.body)
|
|
|
|
},
|
|
|
|
schema: {
|
|
|
|
query: {
|
|
|
|
type: "object",
|
|
|
|
properties: {
|
|
|
|
session_key: { type: "string" },
|
|
|
|
},
|
|
|
|
required: ["session_key"],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
2024-06-16 10:18:19 +00:00
|
|
|
fastify.get("/asset", {
|
|
|
|
async handler(request, reply) {
|
2024-06-16 10:53:12 +00:00
|
|
|
let user = await userFromSessionKey(request.query.session_key)
|
|
|
|
|
|
|
|
if (user.assets.includes(request.query.asset_id)) {
|
|
|
|
let path = join(ASSETS_FOLDER, request.query.asset_id)
|
2024-06-16 10:18:19 +00:00
|
|
|
|
2024-06-16 10:53:12 +00:00
|
|
|
reply.type(mime.getType(path))
|
|
|
|
reply.send(await readFile(path))
|
|
|
|
} else {
|
|
|
|
return "Not authorized"
|
|
|
|
}
|
2024-06-16 10:18:19 +00:00
|
|
|
},
|
|
|
|
schema: {
|
|
|
|
query: {
|
|
|
|
type: "object",
|
|
|
|
properties: {
|
2024-06-16 10:53:12 +00:00
|
|
|
asset_id: { type: "string" },
|
2024-06-16 10:18:19 +00:00
|
|
|
session_key: { type: "string" },
|
|
|
|
},
|
2024-06-16 10:53:12 +00:00
|
|
|
required: ["asset_id", "session_key"],
|
2024-06-16 10:18:19 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
fastify.listen({ port: 3001 })
|
|
|
|
|
|
|
|
function loadM2MKeys() {
|
|
|
|
return {
|
|
|
|
private: readFileSync("../.keys/m2m-dev.pem").toString("ascii"),
|
|
|
|
public: readFileSync("../.keys/m2m-dev.pub").toString("ascii"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function signString(content) {
|
|
|
|
let sign = createSign(M2M_ALGORITHM)
|
|
|
|
sign.update(content)
|
|
|
|
return `-----BEGIN SIGNED MESSAGE-----\n\n${content}\n\n-----BEGIN SIGNATURE-----\n\n${sign.sign(M2M_PRIVATE_KEY, "base64")}\n-----END SIGNATURE-----`
|
2024-06-16 10:53:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function signObject(content) {
|
|
|
|
return signString(JSON.stringify(content))
|
|
|
|
}
|
|
|
|
|
|
|
|
async function userFromSessionKey(session_key) {
|
|
|
|
let url = new URL(IDENTITY_API_ENDPOINT)
|
|
|
|
url.pathname = "/m2m/account"
|
|
|
|
|
|
|
|
let res1 = await fetch(url, {
|
|
|
|
method: "POST",
|
|
|
|
body: signObject({
|
|
|
|
session_key: request.query.session_key,
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
return await res1.json()
|
2024-06-16 10:18:19 +00:00
|
|
|
}
|