diff --git a/backup-server/index.js b/backup-server/index.js index c4248658..b94566fd 100644 --- a/backup-server/index.js +++ b/backup-server/index.js @@ -1,11 +1,12 @@ const start = require('./src/server'); +const PROTOCOL = 'http'; const HOST = '0.0.0.0'; const PORT = 3003; const AUTH_PORT = 3004; const AUTH_SERVER_SEED = '09c2a8437fd9e6e2c7244a8f953270a168a428e903fdfb25b93ff2bec05353e0'; -start({host: HOST, port: PORT, authPort: AUTH_PORT, seed: AUTH_SERVER_SEED}).then(() => { +start({protocol: PROTOCOL, host: HOST, port: PORT, authPort: AUTH_PORT, seed: AUTH_SERVER_SEED}).then(() => { console.log("Server started"); }).catch((error) => { process.exit(1); diff --git a/backup-server/src/authServer.js b/backup-server/src/authServer.js index 3bbd85f1..8594da8c 100644 --- a/backup-server/src/authServer.js +++ b/backup-server/src/authServer.js @@ -2,8 +2,6 @@ const { SlashAuthServer} = require('@slashtags/slashauth') const b4a = require('b4a') const sodium = require('sodium-universal') -const fancyUserDB = new Map(); //TODO actually make fancy - function createKeyPair (seed) { const publicKey = b4a.allocUnsafe(sodium.crypto_sign_PUBLICKEYBYTES) const secretKey = b4a.allocUnsafe(sodium.crypto_sign_SECRETKEYBYTES) @@ -18,41 +16,21 @@ function createKeyPair (seed) { } function createToken () { - const token = b4a.allocUnsafe(sodium.crypto_sign_BYTES) - sodium.randombytes_buf(token) + const token = b4a.allocUnsafe(sodium.crypto_sign_BYTES); + sodium.randombytes_buf(token); - return token.toString('hex') + return token.toString('hex'); } -const createAuthServer = async ({port, host, seed}) => { - console.log(fancyUserDB); - +const createAuthServer = async ({port, host, seed, magiclink}) => { const keypair = createKeyPair(Buffer.from(seed, 'hex')); console.log(`Auth server pub key: ${keypair.publicKey.toString('hex')}`); - const authz = ({ publicKey, token: sessionToken }) => { - console.log('\n**authz**') - console.log(publicKey) - console.log(sessionToken) //TODO do I need this? - console.log('****\n') - - const bearerToken = createToken(); - - // fancyUserDB.set(sessionToken, publicKey); //User has new session - // fancySessionsDB.set(bearerToken, sessionToken); //Bearer token lookup for auth validation - - fancyUserDB.set(bearerToken, publicKey); //User has new session - return { - status: 'ok', - token: bearerToken - } - } - - const magiclink = ({ publicKey }) => { + const authz = ({ publicKey, token }) => { return { - status: 'ok', - ml: 'http://localhost:8000/v0.1/users/123' //Unused for now + status: 'not-supported', + token: '' } } @@ -72,5 +50,4 @@ const createAuthServer = async ({port, host, seed}) => { } exports.createAuthServer = createAuthServer; -exports.createSessionToken = createToken; -exports.fancyUserDB = fancyUserDB; +exports.createToken = createToken; diff --git a/backup-server/src/server.js b/backup-server/src/server.js index 6778bb7e..9103dc25 100644 --- a/backup-server/src/server.js +++ b/backup-server/src/server.js @@ -2,9 +2,11 @@ const Fastify = require('fastify') const FancyStorage = require('./fancyStorage'); const { formatFileSize } = require('./helpers'); -const { createAuthServer, createSessionToken, fancyUserDB } = require('./authServer'); +const { createAuthServer, createToken } = require('./authServer'); -let storage = new FancyStorage(); //TODO actually make fancy +const storage = new FancyStorage(); //TODO actually make fancy +let users = new Map(); // bearer -> pubkey +let mlTokens = new Map(); // mlToken -> pubkey let labels = [ 'ping', @@ -54,18 +56,43 @@ fastify.route({ method: 'GET', url: `/${version}/auth`, handler: async (request, reply) => { - const sessionToken = createSessionToken(); + const sessionToken = createToken(); const slashauthURL = authServer.formatUrl(sessionToken) return {slashauth: slashauthURL}; } }); +//Magic link to get bearer token +fastify.route({ + method: 'POST', + url: `/${version}/auth`, + handler: async (request, reply) => { + const {query} = request; + const {token} = query; + + const pubkey = mlTokens.get(token); + + if (!pubkey) { + reply.code(401); + return {error: "Unauthorized"}; + } + + const bearer = createToken(); + users.set(bearer, pubkey); + + return {bearer}; + } +}); + const authCheckHandler = async (request, reply) => { const bearerToken = request.headers.authorization; - if (!bearerToken || !fancyUserDB.get(bearerToken)) { - reply.code(401).send("Unauthorized"); + const pubkey = users.get(bearerToken); + + if (!bearerToken || !users.has(bearerToken)) { fastify.log.error("Unauthorized or missing token"); + reply.code(401); + return {error: "Unauthorized"}; } } @@ -86,7 +113,7 @@ fastify.route({ const {label, channelId, network} = query; const bearerToken = headers.authorization; - const pubkey = fancyUserDB.get(bearerToken); + const pubkey = users.get(bearerToken); let key = label; let subdir = ''; @@ -118,7 +145,7 @@ fastify.route({ const {label, channelId, network} = query; const bearerToken = headers.authorization; - const pubkey = fancyUserDB.get(bearerToken); + const pubkey = users.get(bearerToken); let key = label; let subdir = ''; @@ -174,9 +201,19 @@ fastify.route({ } }); -module.exports = async ({host, port, authPort, seed}) => { +module.exports = async ({protocol, host, port, authPort, seed}) => { + const magiclink = (publicKey) => { + const mlToken = createToken(); + mlTokens.set(mlToken, publicKey); + + return { + status: 'ok', + ml: `${protocol}://${host}:${port}/${version}/auth?token=${mlToken}`, + } + } + try { - authServer = await createAuthServer({host, port: authPort, seed}); + authServer = await createAuthServer({host, port: authPort, seed, magiclink}); await fastify.listen({ port, host }); } catch (err) { fastify.log.error(err); diff --git a/backup-server/test.js b/backup-server/test.js index 38ed984c..f7ce5d51 100644 --- a/backup-server/test.js +++ b/backup-server/test.js @@ -33,15 +33,27 @@ const getBearerAuthToken = async ({backupServer, seed}) => { // use authServer's publicKey for pinning const client = new SlashAuthClient({ keypair }) - const {status, token} = await client.authz(slashauthURL) + // const {status, token} = await client.authz(slashauthURL) + const { status, ml } = await client.magiclink(slashauthURL); if (status !== 'ok') { throw new Error('Authz failed') } - console.log(`token: ${token}`); + console.log(`ml: ${ml}`); - return token; + //Post to ml link and get token + const mlRes = await fetch(ml, { + method: 'POST' + }); + const mlBody = await mlRes.json(); + console.log(mlBody); + + const {bearer} = mlBody; + + console.log("Using bearer token: " + bearer); + + return bearer; } const testBackup = async (bearerToken) => { diff --git a/example/yarn.lock b/example/yarn.lock index 65c0301f..d8866954 100644 --- a/example/yarn.lock +++ b/example/yarn.lock @@ -1428,7 +1428,7 @@ "@sinonjs/commons" "^1.7.0" "@synonymdev/react-native-ldk@../lib": - version "0.0.103" + version "0.0.104" dependencies: bitcoinjs-lib "^6.0.2"