Hiding API keys in JS setup - javascript

I'm creating a simple UI with an HTML+CSS+JS setup that uses a third-party API requiring a key and I'd like to keep the key in a file that I can gitignore and access from my Javascript file. I'm not going to be deploying this project, I just want to be able to push it to GitHub without temporarily deleting the variable before every commit.
All responses I've found are related to setups with Node.js, React/Webpack, or other server setups, but I don't have a server or transpiler and don't want to add a bunch of cruft and configurations just for this. Is there a way to do that? I tried storing it in a separate JS file and import/export, but either I couldn't get the syntax right or what I was trying needed a transpiler. Every attempt variation resulted in a syntax error or undefined variable.
Key information:
This is project run entirely locally--as in, just opening index.html in my browser--so I don't think I need to worry about the key being exposed in the client.
My setup pretty much just includes index.html, main.js, and style.css.
I want to push the project to GitHub, so I want to store the api key as a variable in a file separate from main.js that I can add to .gitignore but access in main.js.
I'm keeping this as simple as possible without frameworks, etc. Unless it's super simple and lightweight, I don't want to add libraries just to get this working.

Your best bet is to pull whatever secrets you need from the environment itself, either your environment variables or a secrets store.
The specific implementation will depend on what serverless provider you're using, but for example AWS Lambda lets you configure env vars:
https://docs.aws.amazon.com/lambda/latest/dg/env_variables.html
and you can use the Key Management Service or Parameter Store depending on your preference and requirements:
https://aws.amazon.com/blogs/mt/the-right-way-to-store-secrets-using-parameter-store/
Leaving the above in place in case folks find this via looking at the Serverless tag. Updates below based on the updated question.
So, if I understand the updated question correctly, you want to check in all your code to git except the API key, serve the files only on your local file system and have that local copy be able to access the API key.
The simplest way to do this would be to just have another .js file that defines the variable(s) in question like so:
// config.js
var config = { // this should be const instead if you're using ES6 standards
apiKey : '123456789XYZ'
}
Then, in index.html have another script tag that calls that before any scripts that need the config, e.g.:
<script src='./config.js'></script>
<script src='./main.js'></script>
</body>
In main.js you will then be able to reference the variable config for use, and similarly you can .gitignore 'config.js'.

If you use MVC, try to write in php variabel. Than open in script javasript with echo ...

Related

Understanding .env file and environment variables in React JS

I'm relatively new to web development world and now I'm trying to understand the usage of .env file in React JS. So, I have read multiple articles and watch some explanation videos. However, most of them were focusing on how to use it rather what it actually is. Do I understand correctly that the main benefits of using environment variables are:
1)They make it easier to maintain applications since they all stored in one file .env
2)They are not visible to users and are not shown and uploaded to Git repository
Is it correct and is there anything else I need to consider?
They are useful to store site-wide values and settings that don't belong in state or as declarations (deep) in the source.
Important to know is that, for react to use them, they have to start with REACT_APP_. This is due to the environment is a nodejs one, and nodejs will claim all variables unless they start with REACT_APP_
Environment variables starting with REACT_APP_ are embedded in the app code during build time.
Do not store any secrets (such as private keys) as REACT_APP_ variables in there! That will expose them in the JS build.
In your react app you can access the variables like so:
let value = {process.env.REACT_APP_MYVALUE}
In HTML you can use the variables as such:
<title>%REACT_APP_SITE_NAME%</title>
A good quick read on usage with create-react-app: https://create-react-app.dev/docs/adding-custom-environment-variables
Usage
Environment (.env) variables are used to store sensitive information, or as the name says, environment-focused information (live, development, debugging, etc...)
.env file is also kept inside .gitignore, so it does not get pushed to any repositories.
Keeping track of variables
.env.example is a file which is not kept in .gitignore, but it is needed for other developers to know how and what to put in their .env. It looks something like this:
.env.example:
REACT_APP_STRIPE_KEY=
MY_SECRET_KEY=
THIS=
FOO=
BAR=
Basically an empty example of what would be .env. This then gets copied and filled with real values in a .env file, which is only available for that developer on that computer, and is read locally by the scripts which then know in what mode to start the app, connected to what database, with what password etc.
Create a file in the root folder.Its .env file
REACT_APP_(VARIABLE_NAME)=KEY_HERE
Usage:
when you added a variable in .env file. Restart your app.
console.log( process.env.REACT_APP_(VARIABLE_NAME) )
And your .gitignore file, add the bellow code
.env

Intuitive Way to Use JS on Both Front-End and Back-End (Node.JS)

I am making a multiplayer HTML5 game, and have chosen Node.JS so that I can write the game engine and use it both on the client side (For collision detection without network latency) and on the server side (To drive the main game and verify movements and such).
For example, GameEngine.js requires Collision.js, which requires Primitives.js. On my frint-end (for clients) I do this:
<script src="js/Primitives.js"></script>
<script src="js/Collision.js"></script>
<script src="js/GameEngine.js"></script>
This puts everything in the global scope and I just basically use anything I need:
In Primitives.js:
class Rect {
// ...
}
In Collision.js:
class CollisionObject extends Rect {
// ...
}
In Node.JS, things are modular, so I can't just import things like that. My first solution was something like this, if placed at the top of Collision.js:
if (typeof module !== 'undefined'){
const {Rect} = require("./Primitives");
}
A solution I quickly abandoned because it obviously only places Rect in a scope which immediately dies.
Next, I started using the terrible global object and that works but I do not approve of this solution. What's the solution here?
I am willing to modify both how the client loads scripts AND how the server loads scripts in order to achieve my dreams.
Do yourself a favour and use a bundler like webpack as #Mark Meyer suggests.
Your folder structure would look like this:
client
common
server
Whereas the common folder contains the files that are shared by server and client. Instead of using the global scope, you import your files as modules and webpack will create the bundle for you.
You would have a separate webpack configuration file for server and client, but you can setup an automated workflow using npm script where server and client bundles are automatically recompiled on changes (using --watch) and even hot reloaded in the browser.
This may be some overkill for you, but I have created a setup in the past that is isomorphic:
https://github.com/kimgysen/isomorphic-react-setup/tree/master/src
You can get some ideas from it using the webpack configs and npm scripts that you find there.

Reference external script in JavaScript Azure Function code

Goal
I would like a specific JavaScript file to be referenced by multiple JavaScript Azure Functions that are managed by different users in different Azure subscriptions. All the subscriptions are within an enterprise subscription. I would also like these multiple users to be able to alter this single-sourced file.
Proposed solution
My best guess on how to accomplish this is to store the file in a public GitHub repository and have each Function reference it.
Problem
Referencing an external script (in my case, the script hosted in GitHub) in standard ways (as I understand them) does not seem to work when implemented in a JavaScript Azure Function.
Code
Structure:
var abc = require('<external reference>');
Sample external JS file:
https://github.com/<username>/<repo>/blob/master/file.js
Failed attempts
There seem to be many outdated methods documented on SO (e.g., rawgit) but I am looking at the answers last edited in 2018.
https://github.com/<username>/<repo>/blob/master/file.js
https://raw.githubusercontent.com/<username>/<repo>/master/file.js
http://cdn.jsdelivr.net/gh/<username>/<repo>/file.js
Alternatives
I know that in the case that multiple Functions within a single Azure Function (and therefore within the same Azure subscription) can reference a centrally managed file by:
Placing it in a Shared folder, adding "watchDirectories": [ "Shared" ] to host.json, and referencing it with require('../Shared/file.js')
Referencing code in one Function from another (e.g., in Function-2 I can use require('../Function-1/file.js'))
However, unless I misunderstand, neither meets the requirements that the Functions can reside in different Functions in different Azure subscriptions.
I am new to JS. Thank you for any guidance. There may be other ways to satisfy these requirements that I am not thinking of.
You won't be able to require the js files in the typical sense from inside a function, as require uses the filesystem to resolve files, which wouldn't really exist inside of a function. If the js you want to run is available on github you could download the source from github. And use the JS Function constructor to run the create a function you can call. Very roughly it might look something like:
let myfunc;
fetchCodeToRun().then(codeString=>myfunc=new Function(codeString)); //untested
Please note that I'm not specifically too familiar with Azure, and I only have a tiny amount of experience with serverless infrastructure so it's very possible that there's a better way of accomplishing this.
Function constructor docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function

How to use .env file variable in .js file other than Keystone.js?

We are using keystone frame work in one of our project and i am trying to use .env file variable to one of my .js file to connect with http site.I have used dotenv and called process.env.xxyz where xxyz is the variable we are using.Please let me know if there is any other method to call variable from .env file.
Reading process.env is the standard way to retrieve environment variables. See the docs.
The dotenv package you mentioned takes what is in your .env file and puts it in process.env. However, no validation is performed, so it is easy to make mistakes.
Instead, try out my envy module which prevents all of the common mistakes you might be making. It checks for missing variables, amongst other things.
If .env files are still giving you trouble:
Make sure you are using the correct variable names.
Make sure there are no typos.
Make sure you are using the proper syntax.
Consider using command line arguments instead. I recommend meow for this. Also see an example of using envy and meow together.
Regarding syntax: depending on which loader you are using (e.g. dotenv vs envy), the syntax in the .env file could have a big impact on how it is parsed. For example, in Bash and other shells (which the files are based on), each and every one of the following examples behaves entirely differently...
MY_VAR=foo $BAR
MY_VAR='foo $BAR'
MY_VAR="foo $BAR"
Also, environment variable names are case sensitive and by convention are all uppercase. This can lead to mistakes in languages where that is uncommon. In the Node.js program reading process.env, sometimes you might forget that the naming conventions for environment variables are different than the rest of the program.
const myVar = process.env.myVar; // wrong
const myVar = process.env.MY_VAR; // correct
Casing is not an issue if you use envy, as it fixes this by normalizing variable names to camelcase before returning them.
const { myVar } = envy(); // correct, no matter how it is in `.env`
Regardless of which loader you use, you will of course need to call its load function before the .env file will be read. This is pretty much impossible to forget with envy() because you use only its direct return value. But if you are using dotenv, you can easily access process.env at the wrong time because it is already available and populated (but not with all the desired properties) before calling dotenv.config().
Another trick that will help with debugging and save time and effort is to make a dedicated module for configuration. Thanks to the require cache, we avoid doing the work multiple times and also avoid relying upon the loader being idempotent.
Put this in a file called env.js.
const envy = require('envy');
module.exports = envy();
Then import it elsewhere.
const env = require('./env');
Now you have something very simple to debug and it should work the same no matter where you import it.
Just add xxyz=HTTPSiteAddress to your .env file. Then you can call the variable anywhere by using process.env.xxyz.
For example:
var request = require("request");
request(process.env.xxyz, function(error, response, body) {
console.log(body);
});
This will work as long as your keystone.js file contains at the top:
require('dotenv').config();

Including an external javascript library in pebble js file?

Is there any way I can include an external JS library in my pebble code?
Conventionally on a webpage I would do this in my head tags:
<script type='text/javascript' src='https://cdn.firebase.com/js/client/1.0.11/firebase.js'></script>
But in pebble, I am unable to do that since I am only using JS. So how can I include an external library for a JavaScript file.
At present, you cannot include external JS files.
If you're using CloudPebble, then the only way to do this is to copy and paste the content of the JS library files into your JS file.
If you're doing native development, you can modify the wscript file to combine multiple JS files into one at build time.
I think there's some confusion over Pebble.js vs PebbleKit JS (v3.8.1). Pebble.js is a fledgling SDK where eventually the programmer will be able to write pure JavaScript. It's still cooking so there's some functionality missing like the ability to draw a line or obtain the screen dimensions. The repo is a mix of C and JS sources where you can add C code to augment missing functionality but otherwise all your code lives in src/js/app.js or src/js/app/. Anyway, Pebble.js does support require.
I don't use CloudPebble but I got the impression that it either supports Pebble.js (and hence require) or is planning to. I think all this SDK boilerplate code would be hidden.
PebbleKit JS does not support require out of the box AFAIK. I've made a demo that ports require support from Pebble.js to PKJS. The summary of changes is:
Move your project's src/js/pebble-js-app.js to src/js/app/index.js.
Remove any ready event listener from src/js/app/index.js. index.js will
be loaded when the ready event is emitted.
Add src/js/loader.js from Pebble.js.
Add a src/js/main.js that calls require('src/js/app') on the ready event.
Update your wscript with the following
deltas.
When adding new modules, place them under src/js/app/ and require('./name') will work.
I've tried to cover this all in the demo's readme.
BTW, here's the official breakdown of all the different SDKs but it's a little confusing.
I am not sure if there have been changes since the above answer, but it looks like there is in fact a way to include additional resources while keeping things tidy. On the pebbleJS page, there is the following section with an some information on the subject.
GLOBAL NAMESPACE - require(path)
Loads another JavaScript file allowing you to write a multi-file project. Package loading loosely follows the CommonJS format. path is the path to the dependency.
You can then use the following code to "require" a JS library in your pebble project. This should be usable on both Cloud Pebble as well as native development.
// src/js/dependency.js
var dep = require('dependency');
You can then use this as shown below:
dep.myFunction(); // run a function from the dependency
dep.myVar = 2; // access or change variables
Update:
After some digging into this for my own, I have successfully gotten CloudPebble to work with this functionality. It is a bit convoluted, but follows the ECMAScript 6 standards. Below I am posting a simple example of getting things set up. Additionally, I would suggest looking at this code from PebbleJS for a better reference of a complex setup.
myApp.js
var resource = require('myExtraFile'); // require additional library
console.log(resource.value); // logs 42
resource.functionA(); // logs "This is working now"
myExtraFile.js
var myExtraFile = { // create a JSON object to export
"value" : 42, // variable
functionA : function() { // function
console.log("This is working now!");
}
};
this.exports = myExtraFile; // export this function for
// later use

Categories

Resources