added bootstrap page with invite link

This commit is contained in:
Andre Staltz 2024-01-09 10:48:45 +02:00
parent 04a13fbe4b
commit d4698d2dbe
No known key found for this signature in database
GPG Key ID: 9EDE23EA7E8A4890
6 changed files with 84 additions and 5 deletions

View File

@ -11,18 +11,22 @@ const fastifyStatic = require('@fastify/static')
const ejs = require('ejs')
const logger = require('./logger.cjs')
const startPeer = require('./peer.cjs')
const peer = startPeer()
const staticsPath = path.join(__dirname, 'public')
const viewsPath = path.join(__dirname, 'views')
const app = fastify({ logger })
app.register(fastifyView, { engine: { ejs }, root: viewsPath })
app.register(fastifyStatic, { root: staticsPath })
app.get('/', (req, reply) => {
reply.view('homepage.ejs', { markdown: homepageHTML })
if (peer.hub.numMembers() === 0) {
const { port, pubkey, token } = peer.hub.getBootstrap()
reply.view('bootstrap.ejs', { port, pubkey, token })
} else {
reply.view('homepage.ejs', { markdown: homepageHTML })
}
})
app.get('/invite', (req, reply) => {
@ -36,6 +40,5 @@ app.listen(
app.log.error(err)
process.exit(1)
}
startPeer()
}
)

View File

@ -60,6 +60,10 @@ class Members {
if (err) console.warn('Problem saving members file:', err)
})
}
static size() {
return this.#set.size
}
}
module.exports = Members

View File

@ -8,7 +8,7 @@ module.exports = function startPeer() {
const keypairPath = Path.join(path, 'keypair')
const keypair = Keypair.loadOrCreateSync(keypairPath)
SecretStack()
return SecretStack()
.use(require('secret-stack/plugins/net'))
.use(require('secret-handshake-ext/secret-stack'))
.use(require('ssb-conn'))

View File

@ -53,6 +53,10 @@ module.exports = {
Tokens.delete(extra)
Members.add(pubkey)
cb(null, true)
} else if (Members.size() === 0) {
debug('authorized BOOTSTRAP member %s to connect', pubkey)
Members.add(pubkey)
cb(null, true)
} else {
debug('denied stranger %s from connecting', pubkey)
cb(new Error('client is a stranger'))
@ -117,6 +121,17 @@ module.exports = {
createToken() {
return Tokens.create()
},
numMembers() {
return Members.size()
},
getBootstrap() {
const port = config.global.connections.incoming.net[0].port
const pubkey = local.shse.pubkey
const token = 'none'
return { port, pubkey, token }
},
}
},
}

31
lib/public/bootstrap.js vendored Normal file
View File

@ -0,0 +1,31 @@
let hasFocus = true
window.addEventListener('blur', () => {
hasFocus = false
})
window.addEventListener('focus', () => {
hasFocus = true
})
const host = window.location.hostname
const { port, pubkey, token } = window.hubInvite
const uri = `ppppp://invite/join/${host}/${port}/${pubkey}/${token}`
const inviteLinkElem = document.getElementById('invite')
inviteLinkElem.href = uri
// Autoredirect to the PPPPP URI as soon as possible
setTimeout(() => {
window.location.replace(uri)
}, 100)
// Redirect to uri or show failure state
inviteLinkElem.onclick = function handleURI(ev) {
ev.preventDefault()
const uri = inviteLinkElem.href
inviteLinkElem.classList.remove('hidden')
setTimeout(function () {
if (hasFocus) {
inviteLinkElem.classList.add('hidden')
}
}, 5000)
window.location.replace(uri)
}

26
lib/views/bootstrap.ejs Normal file
View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="/style.css" />
</head>
<body>
<article>
<h1>Bootstrap</h1>
<p>
Congratulations on successfully installing this Hub server!
Below is the bootstrap invite link, a one-time invite that will
set you up as the admin of this Hub.
</p>
<a id="invite" class="btn" href="#">Claim invite</a>
<p></p>
</article>
<script>
window.hubInvite = {
port: '<%= port %>',
pubkey: '<%= pubkey %>',
token: '<%= token %>',
};
</script>
<script src="/bootstrap.js"></script>
</body>
</html>