Foreman Multiline ENV Variable Error - node.js

I am trying to pass the contents of my pem file as a string in my .env file using \n to translate the form in the pem file to be used in an ENV variable. The issue, however, is that I'm getting an error from this variable and I'm not sure what it means, but I saw where there was an issue closed allowing for multiline so I'm not sure why this error exists.
Here is my terminal command nf run nodemon app.js
Here is the version 1.4.1
Here is the format of my pem file set within my .env file:
CF_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n
MIIEpAIBAAKCAQEAm7NA5731034RiKsEkuBTrkoBidwFD7hsdfaiohdsfahsdfL99Iw5R4uTA\n
jpPJTOUHTJNMSNF472h42ofnlNflnriNBTPOHNJFRPNSRPFNSRpfPRNFORNFPRSNFpSNFFPNf\n
-----END RSA PRIVATE KEY-----"
This is the error message:
/Users/user/.nvm/versions/node/v4.3.2/lib/node_modules/foreman/lib/envs.js:38
case '"': return /^"([^"]*)"/.exec(val)[1];
^
TypeError: Cannot read property '1' of null
at parseValue (/Users/user/.nvm/versions/node/v4.3.2/lib/node_modules/foreman/lib/envs.js:38:46)

I don't think that it can work like that. It seems that node foreman scans the file line by line and it is trying to create key-value pairs and seems that is not aware of \n or other methods that can split the line. I don't think that you have to put it on more lines, though. Possibly you can do something like that:
CF_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAm7NA57......\n...."
and it is quite possible that will not work. Why don't you put just the filename in the env vars? Something like:
CF_PRIVATE_KEY_FILENAME="my-file-id-rsa"
and when you boot the application:
var id_rsa_contents = fs.readFileSync(__dirname + proces.env.CF_PRIVATE_KEY_FILENAME);

Related

env file format weirdly

I'm working on node project, I'm using .env file to hide some of data. The .env file worked normally, and after I added more informations it got some color letters for variable names and it won't detect my variables when i'm using:
mongodb+srv://MONGODB_USERNAME:MONGODB_PASSWORD#cluster0.ekxmb.mongodb.net/MONGODB_DATABASE_NAME?retryWrites=true&w=majority
I'm having following code in my .env file:
MONGODB_PASSWORD = testpassword;
MONGODB_USERNAME = testuser;
MONGODB_DATABASE_NAME = testdbname;
It works when I manually type in app.js file code like this:
"mongodb+srv://testuser:testpassword#cluster0.ekxmb.mongodb.net/testdbname?retryWrites=true&w=majority"
After I added some additional variables code got formed weirdly with colors on variable names.
Note: It worked with code where I'm importing variables from .env file before, but after weird .env format it won't work.
Putting a variable name in a string will just make it say that variable name. In addition, you don't have the environment variables loaded anywhere.
Install the dotenv npm package for processing the .env file. Then, add this to your code to load the config file:
require('dotenv').config();
Create variables for each of your environment variables from process.env.YOUR_VARIABLE_NAME. An easy way to do this is with destructuring:
let {MONGODB_USERNAME, MONGODB_PASSWORD, MONGODB_DATABASE_NAME} = process.env;
Properly insert these variables into the string. You can use template literals for this:
`mongodb+srv://${MONGODB_USERNAME}:${MONGODB_PASSWORD}#cluster0.ekxmb.mongodb.net/${MONGODB_DATABASE_NAME}?retryWrites=true&w=majority`

Error: error:0909006C:PEM routines:get_name:no start line - node

I have cloned this repo (https://github.com/docusign/code-examples-node) and believe I have entered all required keys and codes. But, when I try to authenticate with JWT I get this error:
at Sign.sign (internal/crypto/sig.js:105:29)
at Object.sign (C:\Users\BrownJ3\Documents\repos\code-examples-node\node_modules\jwa\index.js:152:45)
at Object.jwsSign [as sign] (C:\Users\BrownJ3\Documents\repos\code-examples-node\node_modules\jws\lib\sign-stream.js:32:24)
at Object.module.exports [as sign] (C:\Users\BrownJ3\Documents\repos\code-examples-node\node_modules\docusign-esign\node_modules\jsonwebtoken\sign.js:189:16)
at generateAndSignJWTAssertion (C:\Users\BrownJ3\Documents\repos\code-examples-node\node_modules\docusign-esign\src\ApiClient.js:62:16)
at exports.requestJWTUserToken (C:\Users\BrownJ3\Documents\repos\code-examples-node\node_modules\docusign-esign\src\ApiClient.js:890:19)
at _DsJwtAuth._getToken [as getToken] (C:\Users\BrownJ3\Documents\repos\code-examples-node\lib\DSJwtAuth.js:85:33)
at log (C:\Users\BrownJ3\Documents\repos\code-examples-node\lib\DSJwtAuth.js:174:33)
at _DsJwtAuth.DsJwtAuth.login (C:\Users\BrownJ3\Documents\repos\code-examples-node\lib\DSJwtAuth.js:184:5)
at commonControllers.login (C:\Users\BrownJ3\Documents\repos\code-examples-node\lib\commonControllers.js:36:16) {
library: 'PEM routines',
function: 'get_name',
reason: 'no start line',
code: 'ERR_OSSL_PEM_NO_START_LINE```
What this typically means is that the PEM file is missing the indicator that the key portion has begun.
PEM files are structured like this:
Intitial Data to be processed
-----Begin <Type>-----
Key Information
-----End <Type>-----
The standard for these files can be found here: https://www.rfc-editor.org/rfc/rfc7468
Can you confirm if the -----Begin / End lines are present are present in the PEM file you're using? Please don't post the actual file here, if they are present in the PEM we're going to want to have you open a support case with DocuSign so we keep any necessary private data for troubleshooting private.
If using docker, I have some observations.
Try to make .env values plain text. Not string literal.
When getting the item to code, replace '\\n' with '\n'
You can validate your certificate here: https://www.sslchecker.com/certdecoder.
In my case I pasted wrongly that missed one dash:
- -----BEGIN CERTIFICATE-----
+ ----BEGIN CERTIFICATE-----
Please note the first 5 dash is critical.
If you indeed have valid structure of PEM as #Matt King DS suggested, but you still get this error, it is likely that new lines are causing error.
If you are using dotenv then from documentation:
Multiline values
If you need multiline variables, for example private keys, those are now supported (>= v15.0.0) with line breaks:
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
...
Kh9NV...
...
-----END DSA PRIVATE KEY-----"
Alternatively, you can double quote strings and use the \n character:
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nKh9NV...\n-----END DSA PRIVATE KEY---
AWS lambda
I also encountered this error in AWS lambda. Here above approach didn't work for me. I had to have env variable in lambda without double quotes, with \n instead of new lines and in code I had to replace \n by \n, like this:
process.env.MY_PRIVATE_KEY.replace(/\\n/g, '\n')
Try to delete .nprm from -->
C:\Users{username}
then it will works fine
I solved it by just running the following lines of code. This can be run anywhere in order to turn the normal \n into actual newlines '\n'
jWtstring = 'your_JWT_string'
jWtstring.replace(/\\n/g, '\n')
After you get the newly line-entered JWT key, you can paste it to SSM or perform the next steps as you wish.
const fs = require('fs')
const https = require('https')
https.createServer(
{
key:fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem'),
}
).listen(PORT, () => {
console.log(`server is running on http://localhost:${PORT}`);
})
you need to load the file key.pem before initialize to the "key: key.pem" with readFileSync that belongs to fs module
https.createServer:- https://nodejs.org/api/https.html#httpscreateserveroptions-requestlistener
fs.readFileSync:- https://nodejs.dev/en/learn/reading-files-with-nodejs/
I have exactly the same issue, I spent around 1 week working on this and still no solution for my M1 Mac Pro.
Solved my problem by:
Search for your .npmrc file and delete it.
sudo find ~ -type f -name
'*npmrc' rm -rf /Users/<user>/.npmrc
Do some classics like: npm cache verify npm cache clear --force
Finally use the npm install
Hope it helps, at least for the future user :DD
If you have this problem with Angular CLI then ensure that your ssl key paths are valid.
Had the same problem when running :
ng serve --ssl true --ssl-cert ./ssl/server.crt --ssl-key ./ssl/server.key
and it turned out my paths were invalid.
For the angular version 14.2.8 use following commands.
ng serve --ssl "Your_project_name" --ssl-key "path_of_key" --ssl-cert "path_of_your_certificate"
Example:-if your key and certificate on a same drive C://your_key or C://your_certificate
you have to use
const key = new NodeRSA({ b: 512 });
let keypair = {
private: key.exportKey(),
public: key.exportKey("public")
};
this private key at the time of signing token with RSA
if you just using it as sandbox project you can use: (without private key)
var jwt = require('jsonwebtoken');
var token = jwt.sign({ foo: 'bar' }, 'shhhhh');
if not as sandbox, you have to generate a privteKey.
you can see it on jsonwebtoken docs:
https://www.npmjs.com/package/jsonwebtoken

changes to .env file not recognized

My .env file contains the following line:
DBENV='REMOTE'
when I was using a local database before I had it set to
DBENV='LOCAL'
But when I try to run my file, it does not recognize the change. It thinks it's still set to 'LOCAL':
In fact, when I delete the .env file altogether it still says that. I assume that means it's looking at some other .env file, but I don't know where.
The .env file is located in the root of my project's directory:
How do I get process.env to look at the correct environment file?
Are you remembering to require your .env file properly?
require('dotenv').config()
Also, are you remembering to restart your server after each change?
You are using the assignment operator (single =) in your if expression. This operator returns the value it assigned and is therefore equivalent to
process.env.DBENV = 'LOCAL'
if ('LOCAL') {
//...
}
which always evaluates to true.
Use comparison (== or ===) instead.

Chef: Jenkins cookbook recipe for enabling security

I am currently using the Chef supermarket Jenkins cookbook to deploy an instance of Jenkins. I am attempting to enable security in my configuration of the jenkins instance in the _master_war_.rb recipe file. Code to enable security and create a user using an RSA key is below:
require 'openssl'
require 'net/ssh'
unless node.run_state[:jenkins_private_key]
# defaults to /etc/chef-jenkins-api.key
key_path = node['jenkins_chefci']['jenkins_private_key_path']
begin
Chef::Log.info 'Trying to read private key from ' + key_path + ' for the chef user in jenkins'
key = OpenSSL::PKey::RSA.new File.read(key_path)
Chef::Log.info 'Successfully read existing private key'
rescue
key = OpenSSL::PKey::RSA.new 2048
Chef::Log.info 'Generating new key pair for the chef user in jenkins in ' + key_path
file key_path do
content key.to_pem
mode 0500
sensitive true
end
end
public_key = [key.ssh_type, [key.to_blob].pack('m0'), 'auto-generated key'].join(' ')
# Create the Jenkins user with the public key
jenkins_user 'chef' do
id 'chef#' + Chef::Config[:node_name]
full_name 'Chef Client'
public_keys [public_key]
end
# Set the private key on the Jenkins executor
node.run_state[:jenkins_private_key] = key.to_pem
end
When I attempt to apply this recipe in a run list on a managed node, I receive the following error:
NoMethodError
-------------
undefined method `[]' for nil:NilClass
The stacktrace indicates that the error is related to this particular line of code from my recipe file:
>> key_path = node['jenkins_chefci']['jenkins_private_key_path']
I have seen this error (undefined method `[]' for nil:NilClass), quite a bit online, however have not been able to narrow down the root cause in my recipe. Could I be missing something in my recipe file? I'm wondering if the root cause of the error could be related to these couple lines:
require 'openssl'
require 'net/ssh'

How do you get the path of the running script in groovy?

I'm writing a groovy script that I want to be controlled via a properties file stored in the same folder. However, I want to be able to call this script from anywhere. When I run the script it always looks for the properties file based on where it is run from, not where the script is.
How can I access the path of the script file from within the script?
You are correct that new File(".").getCanonicalPath() does not work. That returns the working directory.
To get the script directory
scriptDir = new File(getClass().protectionDomain.codeSource.location.path).parent
To get the script file path
scriptFile = getClass().protectionDomain.codeSource.location.path
As of Groovy 2.3.0 the #SourceURI annotation can be used to populate a variable with the URI of the script's location. This URI can then be used to get the path to the script:
import groovy.transform.SourceURI
import java.nio.file.Path
import java.nio.file.Paths
#SourceURI
URI sourceUri
Path scriptLocation = Paths.get(sourceUri)
Note that this will only work if the URI is a file: URI (or another URI scheme type with an installed FileSystemProvider), otherwise a FileSystemNotFoundException will be thrown by the Paths.get(URI) call. In particular, certain Groovy runtimes such as groovyshell and nextflow return a data: URI, which will not typically match an installed FileSystemProvider.
This makes sense if you are running the Groovy code as a script, otherwise the whole idea gets a little confusing, IMO. The workaround is here: https://issues.apache.org/jira/browse/GROOVY-1642
Basically this involves changing startGroovy.sh to pass in the location of the Groovy script as an environment variable.
As long as this information is not provided directly by Groovy, it's possible to modify the groovy.(sh|bat) starter script to make this property available as system property:
For unix boxes just change $GROOVY_HOME/bin/groovy (the sh script) to do
export JAVA_OPTS="$JAVA_OPTS -Dscript.name=$0"
before calling startGroovy
For Windows:
In startGroovy.bat add the following 2 lines right after the line with
the :init label (just before the parameter slurping starts):
#rem get name of script to launch with full path
set GROOVY_SCRIPT_NAME=%~f1
A bit further down in the batch file after the line that says "set
JAVA_OPTS=%JAVA_OPTS% -Dgroovy.starter.conf="%STARTER_CONF%" add the
line
set JAVA_OPTS=%JAVA_OPTS% -Dscript.name="%GROOVY_SCRIPT_NAME%"
For gradle user
I have same issue when I'm starting to work with gradle. I want to compile my thrift by remote thrift compiler (custom by my company).
Below is how I solved my issue:
task compileThrift {
doLast {
def projectLocation = projectDir.getAbsolutePath(); // HERE is what you've been looking for.
ssh.run {
session(remotes.compilerServer) {
// Delete existing thrift file.
cleanGeneratedFiles()
new File("$projectLocation/thrift/").eachFile() { f ->
def fileName=f.getName()
if(f.absolutePath.endsWith(".thrift")){
put from: f, into: "$compilerLocation/$fileName"
}
}
execute "mkdir -p $compilerLocation/gen-java"
def compileResult = execute "bash $compilerLocation/genjar $serviceName", logging: 'stdout', pty: true
assert compileResult.contains('SUCCESSFUL')
get from: "$compilerLocation/$serviceName" + '.jar', into: "$projectLocation/libs/"
}
}
}
}
One more solution. It works perfect even you run the script using GrovyConsole
File getScriptFile(){
new File(this.class.classLoader.getResourceLoader().loadGroovySource(this.class.name).toURI())
}
println getScriptFile()
workaround: for us it was running in an ANT environment and storing some location parent (knowing the subpath) in the Java environment properties (System.setProperty( "dirAncestor", "/foo" )) we could access the dir ancestor via Groovy's properties.get('dirAncestor').
maybe this will help for some scenarios mentioned here.

Resources