more magic
This commit is contained in:
parent
e566b16ea6
commit
36a5df1665
4 changed files with 91 additions and 17 deletions
|
@ -1,11 +1,19 @@
|
||||||
import { readFileSync } from "node:fs"
|
import { readFile } from "node:fs/promises"
|
||||||
|
import { readFileSync } from "node:fs";
|
||||||
import { createSign } from "node:crypto";
|
import { createSign } from "node:crypto";
|
||||||
import Fastify from "fastify";
|
import Fastify from "fastify";
|
||||||
|
import { join } from "node:path";
|
||||||
|
import mime from "mime"
|
||||||
|
import { assert } from "node:console";
|
||||||
|
|
||||||
const { private: M2M_PRIVATE_KEY, public: M2M_PUBLIC_KEY } = loadM2MKeys()
|
|
||||||
const M2M_ALGORITHM = "RSA-SHA512"
|
const M2M_ALGORITHM = "RSA-SHA512"
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
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"
|
||||||
|
@ -26,28 +34,45 @@ fastify.get("/crypto/algo", (request, reply) => {
|
||||||
return M2M_ALGORITHM
|
return M2M_ALGORITHM
|
||||||
})
|
})
|
||||||
|
|
||||||
fastify.get("/asset", {
|
fastify.put("/asset", {
|
||||||
async handler(request, reply) {
|
async handler(request, reply) {
|
||||||
let url = new URL(IDENTITY_API_ENDPOINT)
|
let user = await userFromSessionKey(request.query.session_key)
|
||||||
url.pathname = "/auth/account/fromkey"
|
|
||||||
|
|
||||||
let res = await fetch(url, {
|
// continue working onmthis
|
||||||
method: "POST",
|
console.log(typeof request.body)
|
||||||
body: signString(JSON.stringify({
|
|
||||||
session_key: request.query.session_key,
|
|
||||||
}))
|
|
||||||
})
|
|
||||||
|
|
||||||
return await res.text()
|
|
||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
query: {
|
query: {
|
||||||
type: "object",
|
type: "object",
|
||||||
properties: {
|
properties: {
|
||||||
id: { type: "string" },
|
|
||||||
session_key: { type: "string" },
|
session_key: { type: "string" },
|
||||||
},
|
},
|
||||||
required: ["id", "session_key"],
|
required: ["session_key"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
fastify.get("/asset", {
|
||||||
|
async handler(request, reply) {
|
||||||
|
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)
|
||||||
|
|
||||||
|
reply.type(mime.getType(path))
|
||||||
|
reply.send(await readFile(path))
|
||||||
|
} else {
|
||||||
|
return "Not authorized"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
query: {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
asset_id: { type: "string" },
|
||||||
|
session_key: { type: "string" },
|
||||||
|
},
|
||||||
|
required: ["asset_id", "session_key"],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -66,3 +91,21 @@ function signString(content) {
|
||||||
sign.update(content)
|
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-----`
|
return `-----BEGIN SIGNED MESSAGE-----\n\n${content}\n\n-----BEGIN SIGNATURE-----\n\n${sign.sign(M2M_PRIVATE_KEY, "base64")}\n-----END SIGNATURE-----`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
"packageManager": "yarn@4.3.0",
|
"packageManager": "yarn@4.3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fastify": "^4.28.0",
|
"fastify": "^4.28.0",
|
||||||
|
"mime": "^4.0.3",
|
||||||
"uuid": "^10.0.0"
|
"uuid": "^10.0.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -102,6 +102,7 @@ __metadata:
|
||||||
resolution: "asset-api@workspace:."
|
resolution: "asset-api@workspace:."
|
||||||
dependencies:
|
dependencies:
|
||||||
fastify: "npm:^4.28.0"
|
fastify: "npm:^4.28.0"
|
||||||
|
mime: "npm:^4.0.3"
|
||||||
uuid: "npm:^10.0.0"
|
uuid: "npm:^10.0.0"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
@ -312,6 +313,15 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"mime@npm:^4.0.3":
|
||||||
|
version: 4.0.3
|
||||||
|
resolution: "mime@npm:4.0.3"
|
||||||
|
bin:
|
||||||
|
mime: bin/cli.js
|
||||||
|
checksum: 10c0/4be1d06813a581eb9634748919eadab9785857dcfe2af4acca8e4bc340b4b74ff7452c7d3cd76169d0f6b77d7f1ab3434bde8a72ca4291fd150b4205c756c36b
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"on-exit-leak-free@npm:^2.1.0":
|
"on-exit-leak-free@npm:^2.1.0":
|
||||||
version: 2.1.2
|
version: 2.1.2
|
||||||
resolution: "on-exit-leak-free@npm:2.1.2"
|
resolution: "on-exit-leak-free@npm:2.1.2"
|
||||||
|
|
|
@ -24,6 +24,7 @@ let users = {
|
||||||
uid: '005d6417-a23c-48bd-b348-eafeae649b94',
|
uid: '005d6417-a23c-48bd-b348-eafeae649b94',
|
||||||
password: '12345678901234567890',
|
password: '12345678901234567890',
|
||||||
name: 'Jane Doe',
|
name: 'Jane Doe',
|
||||||
|
assets: ["f9d040d6-598c-4483-952f-08e7d35d5420.jpg"],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,10 +36,28 @@ fastify.get('/', async (request, reply) => {
|
||||||
return IDENTITY_API_LANDING_MESSAGE;
|
return IDENTITY_API_LANDING_MESSAGE;
|
||||||
})
|
})
|
||||||
|
|
||||||
fastify.post("/auth/account/fromkey", {
|
fastify.put("/m2m/asset", {
|
||||||
async handler(request, reply) {
|
async handler(request, reply) {
|
||||||
if (!verifySignature(request.body, ASSET_API_PUBKEY)) {
|
if (!verifySignature(request.body, ASSET_API_PUBKEY)) {
|
||||||
reply.statusCode(401)
|
reply.statusCode(401)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let body = JSON.parse(getContentFromSigned(request.body))
|
||||||
|
|
||||||
|
let uid = session_keys[`key:${body.session_key}`]
|
||||||
|
let user = Object.values(users).filter(v => v.uid === uid)
|
||||||
|
assert(user.length === 1)
|
||||||
|
|
||||||
|
users[user[0].email].assets.push(body.asset_id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
fastify.post("/m2m/account", {
|
||||||
|
async handler(request, reply) {
|
||||||
|
if (!verifySignature(request.body, ASSET_API_PUBKEY)) {
|
||||||
|
reply.statusCode(401)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let body = JSON.parse(getContentFromSigned(request.body))
|
let body = JSON.parse(getContentFromSigned(request.body))
|
||||||
|
@ -137,6 +156,7 @@ fastify.post('/auth/register', {
|
||||||
uid: uuidv4(),
|
uid: uuidv4(),
|
||||||
password: request.body.password,
|
password: request.body.password,
|
||||||
name: request.body.name,
|
name: request.body.name,
|
||||||
|
assets: [],
|
||||||
}
|
}
|
||||||
|
|
||||||
let user = users[request.body.email]
|
let user = users[request.body.email]
|
||||||
|
|
Loading…
Reference in a new issue