Merge pull request #473 from shocknet/feature/allow-locked-lnd
unlocked lnd access code page
This commit is contained in:
commit
786e947164
8 changed files with 169 additions and 8 deletions
|
|
@ -19,4 +19,4 @@ TORRENT_SEED_TOKEN=jibberish
|
|||
# "default" or "hosting"
|
||||
DEPLOYMENT_TYPE=hosting
|
||||
# allow to create a user with unlocked lnd
|
||||
ALLOW_UNLOCKED_LND="true"
|
||||
ALLOW_UNLOCKED_LND=false
|
||||
|
|
@ -1 +1,2 @@
|
|||
*.ts
|
||||
/public/*.min.js
|
||||
78
public/localHomepage.html
Normal file
78
public/localHomepage.html
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<script src="/qrCodeGenerator"></script>
|
||||
</head>
|
||||
<body>
|
||||
<p id="errorContainer"></p>
|
||||
<div>
|
||||
<h3>Tunnel</h3>
|
||||
<p id="tunnelState"></p>
|
||||
</div>
|
||||
<div>
|
||||
<h3>Access Secret</h3>
|
||||
<p id="accessSecretState"></p>
|
||||
</div>
|
||||
<div id="qrcode"></div>
|
||||
<script>
|
||||
fetch(`${window.location.origin}/api/accessInfo`)
|
||||
.then(res => res.json())
|
||||
.then(j => {
|
||||
console.log(j)
|
||||
if(j.field){
|
||||
document.querySelector('#errorContainer').innerHTML ='there was an error, unable to load access information, reason: '+ j.message
|
||||
return
|
||||
}
|
||||
|
||||
const tunnelUrl = handleTunnelInfo(j)
|
||||
const accessCode = handleAccessCode(j)
|
||||
|
||||
const baseUrl = tunnelUrl ? tunnelUrl : window.location.host
|
||||
const finalUrl = accessCode ? `${accessCode}#${baseUrl}` : baseUrl
|
||||
new QRCode(document.getElementById("qrcode"), finalUrl);
|
||||
|
||||
})
|
||||
.catch(e => {
|
||||
console.log(e.message)
|
||||
})
|
||||
|
||||
const handleTunnelInfo = (res) => {
|
||||
|
||||
|
||||
const tunnelState = document.querySelector("#tunnelState")
|
||||
if(res.tunnelDisabled){
|
||||
tunnelState.innerHTML = 'The tunnel service is disabled'
|
||||
return
|
||||
}
|
||||
if(res.relayNotFound) {
|
||||
tunnelState.innerHTML = 'The tunnel service seems broken'
|
||||
return
|
||||
}
|
||||
tunnelState.innerHTML = `Tunnel URL: ${res.relayId}@${res.relayUrl}`
|
||||
return `${res.relayId}@${res.relayUrl}`
|
||||
}
|
||||
|
||||
const handleAccessCode = (res) => {
|
||||
const accessSecretState = document.querySelector("#accessSecretState")
|
||||
if(res.accessSecretDisabled){
|
||||
accessSecretState.innerHTML = 'The access secret is disabled'
|
||||
return
|
||||
}
|
||||
if(res.accessCodeNotFound){
|
||||
accessSecretState.innerHTML = 'The access secret seems broken'
|
||||
return
|
||||
}
|
||||
if(res.accessCodeUsed){
|
||||
accessSecretState.innerHTML = 'The access secret was already used'
|
||||
return
|
||||
}
|
||||
accessSecretState.innerHTML = `Access Secret: ${res.accessCode}`
|
||||
return res.accessCode
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
1
public/qrcode.min.js
vendored
Normal file
1
public/qrcode.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -2694,7 +2694,7 @@ module.exports = async (
|
|||
//this is for OBS notifications, not wired with UI.
|
||||
ap.get('/api/subscribeStream', (req, res) => {
|
||||
try {
|
||||
res.sendFile(path.join(__dirname, '/index.html'))
|
||||
res.sendFile(path.join(__dirname, '../public/obsOverlay.html'))
|
||||
} catch (e) {
|
||||
logger.error(e)
|
||||
res.status(500).json({
|
||||
|
|
@ -2750,6 +2750,82 @@ module.exports = async (
|
|||
})
|
||||
}
|
||||
})
|
||||
|
||||
ap.get('/', (req, res) => {
|
||||
try {
|
||||
res.sendFile(path.join(__dirname, '../public/localHomepage.html'))
|
||||
} catch (e) {
|
||||
logger.error(e)
|
||||
res.status(500).json({
|
||||
errorMessage: e.message
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
ap.get('/qrCodeGenerator', (req, res) => {
|
||||
console.log('qrrerrr')
|
||||
try {
|
||||
res.sendFile(path.join(__dirname, '../public/qrcode.min.js'))
|
||||
} catch (e) {
|
||||
logger.error(e)
|
||||
res.status(500).json({
|
||||
errorMessage: e.message
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
ap.get('/api/accessInfo', async (req, res) => {
|
||||
if (req.ip !== '127.0.0.1') {
|
||||
res.json({
|
||||
field: 'origin',
|
||||
message: 'invalid origin, cant serve access info'
|
||||
})
|
||||
return
|
||||
}
|
||||
try {
|
||||
const [relayId, relayUrl, accessSecret] = await Promise.all([
|
||||
Storage.getItem('relay/id'),
|
||||
Storage.getItem('relay/url'),
|
||||
Storage.getItem('FirstAccessSecret')
|
||||
])
|
||||
const response = {}
|
||||
if (config.cliArgs.tunnel) {
|
||||
if (!relayId || !relayUrl) {
|
||||
response.relayNotFound = true
|
||||
} else {
|
||||
response.relayId = relayId
|
||||
response.relayUrl = relayUrl
|
||||
}
|
||||
} else {
|
||||
response.tunnelDisabled = true
|
||||
}
|
||||
|
||||
if (process.env.ALLOW_UNLOCKED_LND !== 'true') {
|
||||
response.accessSecretDisabled = true
|
||||
return res.json(response)
|
||||
}
|
||||
|
||||
if (!accessSecret) {
|
||||
response.accessCodeNotFound = true
|
||||
res.json(response)
|
||||
return
|
||||
}
|
||||
const codeUsed = await Storage.getItem(
|
||||
`UnlockedAccessSecrets/${accessSecret}`
|
||||
)
|
||||
if (codeUsed !== false) {
|
||||
response.accessCodeUsed = true
|
||||
return res.json(response)
|
||||
}
|
||||
response.accessCode = accessSecret
|
||||
res.json(response)
|
||||
} catch (e) {
|
||||
logger.error(e)
|
||||
res.status(500).json({
|
||||
errorMessage: e.message
|
||||
})
|
||||
}
|
||||
})
|
||||
} catch (err) {
|
||||
logger.warn('Unhandled rejection:', err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -382,7 +382,8 @@ const server = program => {
|
|||
app,
|
||||
{
|
||||
...defaults,
|
||||
lndAddress: program.lndAddress
|
||||
lndAddress: program.lndAddress,
|
||||
cliArgs: program
|
||||
},
|
||||
Sockets,
|
||||
{
|
||||
|
|
@ -439,15 +440,16 @@ const server = program => {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
if(process.env.ALLOW_UNLOCKED_LND === 'true'){
|
||||
const codes = await Storage.valuesWithKeyMatch(/^UnlockedAccessSecrets\//u)
|
||||
if(codes.length === 0){
|
||||
const code = generateRandomString(12)
|
||||
const code = await generateRandomString(12)
|
||||
await Storage.setItem(`UnlockedAccessSecrets/${code}`, false)
|
||||
await Storage.setItem(`FirstAccessSecret`, code)
|
||||
logger.info("the access code is:"+code)
|
||||
} else if(codes.length === 1 || codes[0] === false){
|
||||
logger.info("the access code is:"+codes[0])
|
||||
} else if(codes.length === 1 && codes[0] === false){
|
||||
const firstCode = await Storage.getItem("FirstAccessSecret")
|
||||
logger.info("the access code is:"+firstCode)
|
||||
}
|
||||
}
|
||||
serverInstance.listen(serverPort, serverHost)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@ module.exports = {
|
|||
//
|
||||
"/api/gun/auth": true,
|
||||
"/api/subscribeStream":true,
|
||||
"/":true,
|
||||
"/api/accessInfo":true,
|
||||
"/qrCodeGenerator":true,
|
||||
},
|
||||
POST: {
|
||||
"/api/lnd/connect": true,
|
||||
|
|
@ -33,5 +36,5 @@ module.exports = {
|
|||
PUT: {},
|
||||
DELETE: {}
|
||||
},
|
||||
nonEncryptedRoutes: ['/api/security/exchangeKeys', "/api/encryption/exchange", '/healthz', '/ping', '/tunnel/status', '/api/lnd/wallet/status', '/api/gun/auth',"/api/subscribeStream"]
|
||||
nonEncryptedRoutes: ['/api/security/exchangeKeys', "/api/encryption/exchange", '/healthz', '/ping', '/tunnel/status', '/api/lnd/wallet/status', '/api/gun/auth',"/api/subscribeStream", "/", "/api/accessInfo","/qrCodeGenerator"]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue