Skip to content

Commit 8a8b80e

Browse files
Merge pull request ElementsProject#85 from ShahanaFarooqui/fix-grpc-certs-info
Fix grpc certs info
2 parents 1099be6 + 7e4cea9 commit 8a8b80e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+3127
-1322
lines changed

README.md

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -40,36 +40,38 @@
4040
```
4141
4242
- ### Dependency Installation
43-
```
44-
cd cln-application-0.0.1
45-
npm install --omit=dev
46-
```
43+
44+
```
45+
cd cln-application-0.0.1
46+
npm install --force --omit=dev
47+
```
4748
4849
- ### Environment Variables
4950
This application accepts & depends upon these variables to be passed through environment:
5051
5152
```
52-
- APP_CORE_LIGHTNING_IP: IP address of this application (cln-application) container (required)
53-
- APP_CORE_LIGHTNING_PORT: Port on which this application should be served (required)
54-
- APP_CORE_LIGHTNING_DAEMON_IP: IP address of Core lightning node container (required)
55-
- COMMANDO_CONFIG: Full Path including file name for commando auth with PUBKEY & RUNE (required)
56-
- APP_CORE_LIGHTNING_WEBSOCKET_PORT: Core lightning's websocket port (required; from cln's config.json; starting with `bind-addr=ws:`)
57-
- APP_CONFIG_DIR: Path for cln-application's configuration file (required; config.json)
58-
- DEVICE_DOMAIN_NAME: Device name/IP for lnmessage connect url feature (optional; for connect wallet screen)
53+
- SINGLE_SIGN_ON: Flag to bypass application level authentication (valid values: true/false, default: false)
5954
- LOCAL_HOST: Device url for connect url links (optional; for connect wallet screen)
55+
- DEVICE_DOMAIN_NAME: Device name/IP for lnmessage connect url feature (optional; for connect wallet screen)
56+
- BITCOIN_NODE_IP: IP address of bitcoin node container (required)
57+
- BITCOIN_NETWORK: Bitcoin network type (optional; for entrypoint.sh; valid values: bitcoin/signet/testnet/regtest)
58+
- APP_CONFIG_DIR: Path for cln-application's configuration file (required; config.json)
6059
- APP_MODE: Mode for logging and other settings (valid values: production/development/testing, default: production)
61-
- SINGLE_SIGN_ON: Flag to bypass application level authentication (valid values: true/false, default: false)
62-
- APP_PROTOCOL: Protocol on which the application will be served (valid values: http/https, default: http)
63-
- CORE_LIGHTNING_PATH: Path for core lightning (optional; required for entrypoint.sh)
64-
- APP_BITCOIN_NODE_IP: IP address of bitcoin node container (required)
65-
- APP_CORE_LIGHTNING_BITCOIN_NETWORK: Bitcoin network type (optional; for entrypoint.sh; valid values: bitcoin/signet/testnet/regtest)
6660
- APP_CONNECT: Choose how to connect to CLN (valid values: COMMANDO/REST/GRPC, default: COMMANDO)
67-
- APP_CORE_LIGHTNING_REST_PROTOCOL: Protocol on which REST is served (valid values: http/https, default: https)
68-
- APP_CORE_LIGHTNING_REST_PORT: REST server port (optional; for connect wallet screen)
69-
- APP_CORE_LIGHTNING_REST_CERT_DIR: Path for certificates (optional; required if APP_CORE_LIGHTNING_REST_PROTOCOL is https)
70-
- APP_CORE_LIGHTNING_REST_HIDDEN_SERVICE: REST hidden service url (optional; for connect wallet screen; Used for Tor Domain also)
71-
- APP_CORE_LIGHTNING_DAEMON_GRPC_PROTOCOL: Core lightning's GRPC protocol (valid values: http/https, default: http)
72-
- APP_CORE_LIGHTNING_DAEMON_GRPC_PORT: Core lightning's GRPC port (optional; future proofing for connect wallet screen)
61+
- APP_PROTOCOL: Protocol on which the application will be served (valid values: http/https, default: http)
62+
- APP_IP: IP address of this application (cln-application) container (required)
63+
- APP_PORT: Port on which this application should be served (required)
64+
- LIGHTNING_IP: IP address of Core lightning node container (required)
65+
- LIGHTNING_PATH: Path for core lightning (optional; required for entrypoint.sh)
66+
- HIDDEN_SERVICE_URL: REST hidden service url (optional; for connect wallet screen; Used for Tor Domain also)
67+
- LIGHTNING_NODE_TYPE: Choose Core lightning node type (valid values: CLN/GREENLIGHT, default: CLN)
68+
- COMMANDO_CONFIG: Full Path including file name for commando auth with PUBKEY & RUNE (required)
69+
- LIGHTNING_WEBSOCKET_PORT: Core lightning's websocket port (required; from cln's config.json; starting with `bind-addr=ws:`)
70+
- LIGHTNING_REST_PROTOCOL: Protocol on which REST is served (valid values: http/https, default: https)
71+
- LIGHTNING_REST_PORT: REST server port (required if APP_CONNECT is REST)
72+
- LIGHTNING_CERTS_DIR: Path for core lightning certificates (Required if APP_CONNECT is REST/GRPC with PROTOCOL 'https')
73+
- LIGHTNING_GRPC_PROTOCOL: Core lightning's GRPC protocol (valid values: http/https, default: http)
74+
- LIGHTNING_GRPC_PORT: Core lightning's GRPC port (Required if APP_CONNECT is GRPC)
7375
```
7476
7577
Set these variables either via terminal OR by env.sh script OR by explicitly loading variables from .env files.
@@ -106,7 +108,7 @@
106108
107109
- ### Start The Application
108110
- Setup environment variables either via terminal OR by env.sh script OR by explicitly loading variables from .env files.
109-
- Run `start` script for starting your application's server at port `APP_CORE_LIGHTNING_PORT`
111+
- Run `start` script for starting your application's server at port `APP_PORT`
110112
111113
```
112114
npm run start

apps/backend/dist/controllers/auth.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,17 @@ class AuthController {
4141
const isValid = req.body.isValid;
4242
const currPassword = req.body.currPassword;
4343
const newPassword = req.body.newPassword;
44-
if (fs.existsSync(APP_CONSTANTS.CONFIG_LOCATION)) {
44+
if (fs.existsSync(APP_CONSTANTS.APP_CONFIG_FILE)) {
4545
try {
46-
const config = JSON.parse(fs.readFileSync(APP_CONSTANTS.CONFIG_LOCATION, 'utf-8'));
46+
const config = JSON.parse(fs.readFileSync(APP_CONSTANTS.APP_CONFIG_FILE, 'utf-8'));
4747
if (config.password === currPassword || !isValid) {
4848
try {
4949
if (typeof config.singleSignOn === 'undefined') {
5050
config.singleSignOn = process.env.SINGLE_SIGN_ON || false;
5151
}
5252
config.password = newPassword;
5353
try {
54-
fs.writeFileSync(APP_CONSTANTS.CONFIG_LOCATION, JSON.stringify(config, null, 2), 'utf-8');
54+
fs.writeFileSync(APP_CONSTANTS.APP_CONFIG_FILE, JSON.stringify(config, null, 2), 'utf-8');
5555
const token = jwt.sign({ userID: SECRET_KEY }, SECRET_KEY);
5656
res.cookie('token', token, { httpOnly: true, maxAge: 3600 * 24 * 7 });
5757
res.status(201).json({ isAuthenticated: true, isValidPassword: isValidPassword() });

apps/backend/dist/controllers/shared.js

Lines changed: 11 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
import axios from 'axios';
22
import * as fs from 'fs';
3-
import { join } from 'path';
43
import { APP_CONSTANTS, DEFAULT_CONFIG, FIAT_RATE_API, FIAT_VENUES, HttpStatusCode, } from '../shared/consts.js';
54
import { logger } from '../shared/logger.js';
65
import handleError from '../shared/error-handler.js';
76
import { APIError } from '../models/errors.js';
8-
import { setSharedApplicationConfig, overrideSettingsWithEnvVariables } from '../shared/utils.js';
9-
import { sep } from 'path';
7+
import { setSharedApplicationConfig, overrideSettingsWithEnvVariables, refreshEnvVariables, } from '../shared/utils.js';
108
import { CLNService } from '../service/lightning.service.js';
119
class SharedController {
1210
getApplicationSettings(req, res, next) {
1311
try {
14-
logger.info('Getting Application Settings from ' + APP_CONSTANTS.CONFIG_LOCATION);
15-
if (!fs.existsSync(APP_CONSTANTS.CONFIG_LOCATION)) {
16-
fs.writeFileSync(APP_CONSTANTS.CONFIG_LOCATION, JSON.stringify(DEFAULT_CONFIG, null, 2), 'utf-8');
12+
logger.info('Getting Application Settings from ' + APP_CONSTANTS.APP_CONFIG_FILE);
13+
if (!fs.existsSync(APP_CONSTANTS.APP_CONFIG_FILE)) {
14+
fs.writeFileSync(APP_CONSTANTS.APP_CONFIG_FILE, JSON.stringify(DEFAULT_CONFIG, null, 2), 'utf-8');
1715
}
18-
let config = JSON.parse(fs.readFileSync(APP_CONSTANTS.CONFIG_LOCATION, 'utf-8'));
16+
let config = JSON.parse(fs.readFileSync(APP_CONSTANTS.APP_CONFIG_FILE, 'utf-8'));
1917
config = overrideSettingsWithEnvVariables(config);
2018
setSharedApplicationConfig(config);
2119
delete config.password;
@@ -28,9 +26,9 @@ class SharedController {
2826
setApplicationSettings(req, res, next) {
2927
try {
3028
logger.info('Updating Application Settings: ' + JSON.stringify(req.body));
31-
const config = JSON.parse(fs.readFileSync(APP_CONSTANTS.CONFIG_LOCATION, 'utf-8'));
29+
const config = JSON.parse(fs.readFileSync(APP_CONSTANTS.APP_CONFIG_FILE, 'utf-8'));
3230
req.body.password = config.password; // Before saving, add password in the config received from frontend
33-
fs.writeFileSync(APP_CONSTANTS.CONFIG_LOCATION, JSON.stringify(req.body, null, 2), 'utf-8');
31+
fs.writeFileSync(APP_CONSTANTS.APP_CONFIG_FILE, JSON.stringify(req.body, null, 2), 'utf-8');
3432
res.status(201).json({ message: 'Application Settings Updated Successfully' });
3533
}
3634
catch (error) {
@@ -40,60 +38,8 @@ class SharedController {
4038
getWalletConnectSettings(req, res, next) {
4139
try {
4240
logger.info('Getting Connection Settings');
43-
const CERTS_PATH = process.env.CORE_LIGHTNING_PATH + sep + process.env.APP_BITCOIN_NETWORK + sep;
44-
let macaroon = '';
45-
let clientKey = '';
46-
let clientCert = '';
47-
let caCert = '';
48-
let packageData = '{ version: "0.0.4" }';
49-
let macaroonFile = join(APP_CONSTANTS.CERT_PATH || '.', 'access.macaroon');
50-
if (fs.existsSync(macaroonFile)) {
51-
logger.info('Getting REST Access Macaroon from ' + APP_CONSTANTS.CERT_PATH);
52-
macaroon = Buffer.from(fs.readFileSync(macaroonFile)).toString('hex');
53-
}
54-
if (fs.existsSync('package.json')) {
55-
packageData = Buffer.from(fs.readFileSync('package.json')).toString();
56-
}
57-
if (fs.existsSync(CERTS_PATH + 'client-key.pem')) {
58-
clientKey = fs.readFileSync(CERTS_PATH + 'client-key.pem').toString();
59-
clientKey = clientKey
60-
.replace(/(\r\n|\n|\r)/gm, '')
61-
.replace('-----BEGIN PRIVATE KEY-----', '')
62-
.replace('-----END PRIVATE KEY-----', '');
63-
}
64-
if (fs.existsSync(CERTS_PATH + 'client.pem')) {
65-
clientCert = fs.readFileSync(CERTS_PATH + 'client.pem').toString();
66-
clientCert = clientCert
67-
.replace(/(\r\n|\n|\r)/gm, '')
68-
.replace('-----BEGIN CERTIFICATE-----', '')
69-
.replace('-----END CERTIFICATE-----', '');
70-
}
71-
if (fs.existsSync(CERTS_PATH + 'ca.pem')) {
72-
caCert = fs.readFileSync(CERTS_PATH + 'ca.pem').toString();
73-
caCert = caCert
74-
.replace(/(\r\n|\n|\r)/gm, '')
75-
.replace('-----BEGIN CERTIFICATE-----', '')
76-
.replace('-----END CERTIFICATE-----', '');
77-
}
78-
CLNService.refreshEnvVariables();
79-
const CONNECT_WALLET_SETTINGS = {
80-
LOCAL_HOST: process.env.LOCAL_HOST || '',
81-
DEVICE_DOMAIN_NAME: process.env.DEVICE_DOMAIN_NAME || '',
82-
TOR_HOST: process.env.APP_CORE_LIGHTNING_REST_HIDDEN_SERVICE || '',
83-
WS_PORT: process.env.APP_CORE_LIGHTNING_WEBSOCKET_PORT || '',
84-
GRPC_PORT: process.env.APP_CORE_LIGHTNING_DAEMON_GRPC_PORT || '',
85-
CLIENT_KEY: clientKey,
86-
CLIENT_CERT: clientCert,
87-
CA_CERT: caCert,
88-
REST_PORT: process.env.APP_CORE_LIGHTNING_REST_PORT || '',
89-
REST_MACAROON: macaroon,
90-
CLN_NODE_IP: process.env.APP_CORE_LIGHTNING_DAEMON_IP || '',
91-
NODE_PUBKEY: process.env.LIGHTNING_PUBKEY || '',
92-
COMMANDO_RUNE: process.env.COMMANDO_RUNE,
93-
APP_VERSION: JSON.parse(packageData).version || '',
94-
INVOICE_RUNE: process.env.INVOICE_RUNE || '',
95-
};
96-
res.status(200).json(CONNECT_WALLET_SETTINGS);
41+
refreshEnvVariables();
42+
res.status(200).json(APP_CONSTANTS);
9743
}
9844
catch (error) {
9945
handleError(error, req, res, next);
@@ -130,9 +76,9 @@ class SharedController {
13076
const showRunes = await CLNService.call('showrunes', []);
13177
const invoiceRune = showRunes.runes.find(rune => rune.restrictions.some(restriction => restriction.alternatives.some(alternative => alternative.value === 'invoice')) &&
13278
rune.restrictions.some(restriction => restriction.alternatives.some(alternative => alternative.value === 'listinvoices')));
133-
if (invoiceRune && fs.existsSync(APP_CONSTANTS.COMMANDO_ENV_LOCATION)) {
79+
if (invoiceRune && fs.existsSync(APP_CONSTANTS.COMMANDO_CONFIG)) {
13480
const invoiceRuneString = `INVOICE_RUNE="${invoiceRune.rune}"\n`;
135-
fs.appendFileSync(APP_CONSTANTS.COMMANDO_ENV_LOCATION, invoiceRuneString, 'utf-8');
81+
fs.appendFileSync(APP_CONSTANTS.COMMANDO_CONFIG, invoiceRuneString, 'utf-8');
13682
res.status(201).send();
13783
}
13884
else {

apps/backend/dist/server.js

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ let directoryName = dirname(fileURLToPath(import.meta.url));
1818
let routes = [];
1919
const app = express();
2020
const server = http.createServer(app);
21-
const LIGHTNING_PORT = normalizePort(process.env.APP_CORE_LIGHTNING_PORT || '2103');
22-
const APP_CORE_LIGHTNING_IP = process.env.APP_CORE_LIGHTNING_IP || 'localhost';
21+
const LIGHTNING_PORT = normalizePort(process.env.APP_PORT || '2103');
22+
const APP_IP = process.env.APP_IP || 'localhost';
2323
const APP_PROTOCOL = process.env.APP_PROTOCOL || 'http';
2424
function normalizePort(val) {
2525
var port = parseInt(val, 10);
@@ -44,7 +44,7 @@ app.use((req, res, next) => {
4444
const corsOptions = {
4545
methods: 'GET, POST, PATCH, PUT, DELETE, OPTIONS',
4646
origin: APP_CONSTANTS.APP_MODE === Environment.PRODUCTION
47-
? APP_PROTOCOL + '://' + APP_CORE_LIGHTNING_IP + ':' + LIGHTNING_PORT
47+
? APP_PROTOCOL + '://' + APP_IP + ':' + LIGHTNING_PORT
4848
: APP_PROTOCOL + '://localhost:4300',
4949
credentials: true,
5050
allowedHeaders: 'Content-Type, X-XSRF-TOKEN, XSRF-TOKEN',
@@ -67,14 +67,9 @@ const throwApiError = (err) => {
6767
logger.error('Server error: ' + err);
6868
switch (err.code) {
6969
case 'EACCES':
70-
return new APIError(HttpStatusCode.ACCESS_DENIED, APP_PROTOCOL +
71-
'://' +
72-
APP_CORE_LIGHTNING_IP +
73-
':' +
74-
LIGHTNING_PORT +
75-
' requires elevated privileges');
70+
return new APIError(HttpStatusCode.ACCESS_DENIED, APP_PROTOCOL + '://' + APP_IP + ':' + LIGHTNING_PORT + ' requires elevated privileges');
7671
case 'EADDRINUSE':
77-
return new APIError(HttpStatusCode.ADDR_IN_USE, APP_PROTOCOL + '://' + APP_CORE_LIGHTNING_IP + ':' + LIGHTNING_PORT + ' is already in use');
72+
return new APIError(HttpStatusCode.ADDR_IN_USE, APP_PROTOCOL + '://' + APP_IP + ':' + LIGHTNING_PORT + ' is already in use');
7873
case 'ECONNREFUSED':
7974
return new APIError(HttpStatusCode.UNAUTHORIZED, 'Server is down/locked');
8075
case 'EBADCSRFTOKEN':
@@ -84,5 +79,5 @@ const throwApiError = (err) => {
8479
}
8580
};
8681
server.on('error', throwApiError);
87-
server.on('listening', () => logger.warn('Server running at ' + APP_PROTOCOL + '://' + APP_CORE_LIGHTNING_IP + ':' + LIGHTNING_PORT));
88-
server.listen({ port: LIGHTNING_PORT, host: APP_CORE_LIGHTNING_IP });
82+
server.on('listening', () => logger.warn('Server running at ' + APP_PROTOCOL + '://' + APP_IP + ':' + LIGHTNING_PORT));
83+
server.listen({ port: LIGHTNING_PORT, host: APP_IP });

apps/backend/dist/service/grpc.service.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ export class GRPCService {
3232
};
3333
if (APP_CONSTANTS.LIGHTNING_GRPC_PROTOCOL === 'https') {
3434
const httpsAgent = new https.Agent({
35-
cert: fs.readFileSync(path.join(APP_CONSTANTS.CERT_PATH || '.', 'client.pem')),
36-
key: fs.readFileSync(path.join(APP_CONSTANTS.CERT_PATH || '.', 'client-key.pem')),
37-
ca: fs.readFileSync(path.join(APP_CONSTANTS.CERT_PATH || '.', 'ca.pem')),
35+
cert: fs.readFileSync(path.join(APP_CONSTANTS.LIGHTNING_CERTS_PATH || '.', 'client.pem')),
36+
key: fs.readFileSync(path.join(APP_CONSTANTS.LIGHTNING_CERTS_PATH || '.', 'client-key.pem')),
37+
ca: fs.readFileSync(path.join(APP_CONSTANTS.LIGHTNING_CERTS_PATH || '.', 'ca.pem')),
3838
});
3939
this.axiosConfig.httpsAgent = httpsAgent;
4040
}

apps/backend/dist/service/lightning.service.js

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ import { LightningError } from '../models/errors.js';
88
import { GRPCService } from './grpc.service.js';
99
import { HttpStatusCode, APP_CONSTANTS, AppConnect, LN_MESSAGE_CONFIG, REST_CONFIG, GRPC_CONFIG, } from '../shared/consts.js';
1010
import { logger } from '../shared/logger.js';
11-
import { readFileSync } from 'fs';
11+
import { refreshEnvVariables } from '../shared/utils.js';
1212
export class LightningService {
1313
clnService = null;
1414
constructor() {
1515
try {
1616
logger.info('Getting Commando Rune');
17-
if (fs.existsSync(APP_CONSTANTS.COMMANDO_ENV_LOCATION)) {
18-
this.refreshEnvVariables();
17+
if (fs.existsSync(APP_CONSTANTS.COMMANDO_CONFIG)) {
18+
refreshEnvVariables();
1919
switch (APP_CONSTANTS.APP_CONNECT) {
2020
case AppConnect.REST:
2121
logger.info('REST connecting with config: ' + JSON.stringify(REST_CONFIG));
@@ -50,7 +50,7 @@ export class LightningService {
5050
headers,
5151
};
5252
if (APP_CONSTANTS.LIGHTNING_REST_PROTOCOL === 'https') {
53-
const caCert = fs.readFileSync(join(APP_CONSTANTS.CERT_PATH || '.', 'ca.pem'));
53+
const caCert = fs.readFileSync(join(APP_CONSTANTS.LIGHTNING_CERTS_PATH || '.', 'ca.pem'));
5454
const httpsAgent = new https.Agent({
5555
ca: caCert,
5656
});
@@ -110,34 +110,5 @@ export class LightningService {
110110
});
111111
}
112112
};
113-
refreshEnvVariables() {
114-
const envVars = this.parseEnvFile(APP_CONSTANTS.COMMANDO_ENV_LOCATION);
115-
process.env.LIGHTNING_PUBKEY = envVars.LIGHTNING_PUBKEY;
116-
process.env.COMMANDO_RUNE = envVars.LIGHTNING_RUNE;
117-
process.env.INVOICE_RUNE = envVars.INVOICE_RUNE !== undefined ? envVars.INVOICE_RUNE : '';
118-
APP_CONSTANTS.COMMANDO_RUNE = process.env.COMMANDO_RUNE;
119-
APP_CONSTANTS.NODE_PUBKEY = process.env.LIGHTNING_PUBKEY;
120-
LN_MESSAGE_CONFIG.remoteNodePublicKey = process.env.LIGHTNING_PUBKEY;
121-
GRPC_CONFIG.pubkey = process.env.LIGHTNING_PUBKEY;
122-
}
123-
parseEnvFile(filePath) {
124-
try {
125-
const content = readFileSync(filePath, 'utf8');
126-
const lines = content.split('\n');
127-
const envVars = {};
128-
for (let line of lines) {
129-
line = line.trim();
130-
if (line && line.indexOf('=') !== -1 && !line.startsWith('#')) {
131-
const [key, ...value] = line.split('=');
132-
envVars[key] = value.join('=').replace(/(^"|"$)/g, '');
133-
}
134-
}
135-
return envVars;
136-
}
137-
catch (err) {
138-
logger.error('Error reading .commando-env file:', err);
139-
return {};
140-
}
141-
}
142113
}
143114
export const CLNService = new LightningService();

0 commit comments

Comments
 (0)