what is the point of using react environment variables? - reactjs

Reacts documentation says "Environment variables are embedded into the build, meaning anyone can view them by inspecting your app's files".
I am assuming its because the .env. file where I would define them will be included in the build (or not because of that?!)?
So then,what the point of using react environment variables if i cannot hide any keys?
Or do I just not understand it and I can hide keys using react environment variables (a tutorial I am watching says you can hide them using it)?
What if I define those variables inside my shell? Are they exposed as well?
Thank you!!

Environment variables help because they can let you customize settings without changing the source code. In terms of the code that runs, the end result is the same - yes, whatever client runs the code will be able to see what's going on, including any API keys you include with the app - but it makes the development process easier when there's a single place where you can set settings that can differ between environments without changing the code itself.
This is of the greatest benefit when using source control like Git. If you make a change to a build setting - such as the change to an API key - it wouldn't make sense for that change to be checked into the codebase's history. Rather, the convention is to instead have the application read its environment variables, and have those not checked into source control, allowing the settings to be easily changed without changing anything else in the application's code itself.
See An Introduction to Environment Variables and How to Use Them for a decent summary.
if i cannot hide any keys?
Hiding API keys is a completely separate issue - it's not something that environment variables are meant to solve. If you want to hide your keys, there are at least two approaches:
Put the keys on your server, and then have the client make requests to your server, and have your server use the (secret) API key to the external service, then echo the result back to the client
Some APIs which provide keys also provide the ability to whitelist requests from certain domains, and to block requests from others. For example, depending on what you're using, you may have the ability to go into the API's settings to enable your key with mysite.com, and block it from being recognized as valid from any other site. This way, even if the API key is public, it's not (much) of a problem.

Environmental variables in react are always prefixed with REACT_APP_ and are used when you want to change values across your frontend react application. They're not designed to hide API keys which are intended to be private.
Variables that do not start with that prefix will not be visible in the final build (You can also use two .env files).
No variables defined inside your server shell will be exposed.

Related

Environment variable as custom metadata type in Salesforce

I am trying to represent environment variables in the Salesforce codebase and came across Custom Metadata Types. So based on which Sandbox I am in, I want to vary the baseURL of an external service that I am hitting from my apex class. I want to avoid hard coding anything in the class, and hence trying to find out an environment variable like solution.
How would you represent the URL as a custom metadata type? Also, how can I access it in the class? What happens when a qa sandbox is refreshed from prod? Do they custom metadata type records get overridden?
How are you calling that external service? If it's truly a base url you might be better of using "named credential" for it. It'll abstract the base url away for you, include authentication or certificate if you have to present any...
Failing that - custom metadata might be a poor choice. They're kind of dictionary objects, you can add more (but not from apex) but if you deploy stuff using Git/Ant/SFDX CLI rather than changesets it'd become bit pain, you'd need different custom metadata value for sandbox vs prod. Kinda defeats the purpose.
You might be better off using custom setting instead (hierarchy is enabled by default, list you'd have to flip a checkbox in setup. List is useful if you need key-value kind of pairs, similar to custom metadata): https://salesforce.stackexchange.com/questions/74049/what-is-the-difference-between-custom-settings-and-custom-metadata-types
And you can modify them with Apex too. Which means that in ideal world you could have a "postcopy" class running as soon as sandbox is refreshed that overwrites the custom setting with the non-prod value. For named credential I don't think you can pull it off, you'd need a mini deployment that changes it or manual step (have you seen https://salesforce.stackexchange.com/q/955/799 ?)

Different branding for same codebase

Im in a project where we will create different sites using the same codebase.
I would like to have a brand style and config for each site which I specify somehow in my build process.
Anyone have an idea of the best way to achieve this ?
I would treat the different sites in much the same way I'd treat different environment (dev, test, prod). If there aren't a lot of changes, just use environment variables on each server where the site will run that define which site it is. Your code can then conditionally do things (e.g. add a class site-x to the body for styling).
You can use something like dotenv to make setting environment vars easier (remember Windows does it differently to *NIX) if you're setting environments in a script. That way you're changing a file rather then actual environment variables when you want to test what a particular site looks like.
If there are many different config items that are different between sites then you can have multiple config files (config-site-one.js, config-site-two.js) and a central config.js file that returns the correct config based on some environment variable like MY_SITE_NAME.
However if you actually want to package up the site to 'send' somewhere (?) then you could run your build command with a flag like webpack blahblahblah --site=site-one.
You can use yargs to get that 'site' variable and use it in your build process however you like.

Angular Constant Best Practice

I have an angular constant which defines webservice end point
angular.module('myModule').constant('mywebservice_url', 'http://192.168.1.100')
The problem is that for dev I have a different end point while staging and production its different. Every time I try to check in to git I have to manually reset this file.
Is there any way git permenantly ignore this file but checks out the file while clone or checkout?
Is there any way I can make angular pickup file dynamically from something like environment variable.
NOTE: I don't want to depend on server to do this, ie I don't want to use apach SSI or any of those technologies as it will work only one set of servers.
Delaying the injection via backend processing. I usually just create a global object on html page called pageSettings which values like this is getting injected from the backend, i.e. environment variables, etc. and just pass that global pageSettings object into that angular constant or value.
Build system injection. If you don't have a backend, i.e. pure SPA... maybe you can put this inside your build system, i.e. create multiple task for building the different environments in gulp or grunt and replace that value during the build process.
In e.a. your app init code:
var x = location.hostname;
Then define 2 different constants.
One based off the domain name of your develop environment and one for your production.

Storing user data for a C-based Native Client instance

I have been working on C-based Native Client module for Google Chrome. Many of the module functions that are called by the NaCl system have a parameter of PP_Instance which uniquely identifies the module instance.
My question: Is there any way to associate user data with this instance handle?
The C API specifies that it is an opaque handle. It provides no functions for linking user data to the handle. Right now, I have to use a bunch of global variables within the module to share state among the functions. It doesn't feel like the right solution. I'm not sure if more than one instance will ever share the process space but I'm not making any assumptions here.
I suppose I could implement some sort of look up table to map instances to unique contexts that happen to live in the global scope. But that also seems like it should be unnecessary for a C-based API. The C++ API avoids this by virtue of its classes.
PP_Instance should be used as a key to lookup state / object associated with the plugin instance. More than one plugin instance may be instantiated in a module as per the API, when, for example, multiple embed tags are present in the containing frame. Currently the NaCl implementation of Pepper does not do this -- instead, multiple processes each containing a single module each instantiating a single pepper plugin instance is created. However, this is an implementation detail (or maybe bug?) that is subject to change, and it would be better to defensively program and be able to handle multiple DidCreate events.
Of course, if your NaCl module is guaranteed to never be used by anyone else and you know you won't ever have two embeds of the same module, then it might be okay to assume singleton instance and use global state, but doing things the "right" way isn't that hard, so why not?
See native-client-discuss thread for more discussion on this topic.

Environment.SpecialFolderPath vs .NET Settings (& resolving environment variables in textbox binding)

I'm a C# noob, and I've been looking for info on best practices for C# application development.
I want to have an application setting that defines where the application will write its log files & reporting output. I want this to default to %USERPROFILE%\Documents\<Vendor>\<Tool>, since these files are created for the user to actually look at and dispose of at their leisure. But, if the user wants the files to be written to some other location, I want to persist their preferences.
My research so far indicates that:
It's not generally a good idea to use environment variables directly. Instead, it's recommended to use the Environment.GetFolderPath method and the Environment.SpecialFolders enum to get access to special locations in Windows like the user profile.
But, it's recommended to use user-scope .NET Application Settings to persist settings from one session to another.
Is there any good way to reconcile best practice 1 and best practice 2? Is it actually possible to store this default location in the Application Settings in a compatible way without referencing the %USERPROFILE% environment variable?
A related question:
Assume I keep %USERPROFILE%\Documents\<vendor>\<tool> as the default value for the Setting. I want the Setting's value to be bound to a textbox on the main application form (with a Browse button to select a new path). How can I bind the Setting to a textbox in such a way that %USERPROFILE% is resolved to a conventional filesystem path (eg C:\Users\<username>\Documents\<vendor>\<tool>) for purposes of display to the user?
I think that storing paths with environment variables is actually the best way to reference a special folder as a string and still make the path easily editable by the user, should s/he decide to do so.
Environment variables can be resolved to a simple string in .NET by calling the Environment.ExpandEnvironmentVariables method. You can use this method just before presenting the path in your TextBox and thus make it easily editable for the user. Once the user customizes the path, you can store it as an absolute path from there on, I suppose.

Resources