API keys exposed as 'strings' in my public git respositories - javascript

I have code like this in my git respository, but it is not a good idea beacuse my API keys are exposed in strings and everyone can see it.
So my question is how can I handle this problem? Should I save this API keys to *.txt file and import this strings?. And add this txt file to .gitignore file?
Can you suggest what would be the proper way of tackling this problem?
import axios from 'axios';
export const FETCH_LOCATION = 'FETCH_LOCATION';
export const FETCH_WEATHER = 'FETCH_WEATHER';
export const HISTORY_SELECTED = 'HISTORY_SELECTED';
export const SHOW_INFO = 'SHOW_INFO';
const API_KEY_GOOGLE = 'string';
const API_KEY_WUNDERGROUND = 'string';
export function fetchLocation(city) {
const urlGoogle = `https://maps.googleapis.com/maps/api/geocode/json?address=${city}&key=${API_KEY_GOOGLE}`;
const request = axios.get(urlGoogle);

A common practice is to use .env files, and ignore .env in .gitignore. You will load these files into process.env. You can use a package called dotenv.
For example, if I need a google API, I create a file call .env, then store it like
GOOGLEAPIKEY=asdfewvger343sdfasdf
If you are loading it with webpack, then add it as a plugin
import DotEnvPlugin from 'webpack-dotenv-plugin';
plugins: [
new DotenvPlugin({
sample: './.env.default',
path: './.env.dev',
}),
...
]
Or you can just use dotenv
require('dotenv').config()
This will load .env file from your root without config.
Read more on this
https://github.com/motdotla/dotenv
In your app, you will use googleapi, like process.env.GOOGLEAPIKEY
const data = await axios
.post(`localhost:3000/api/helloworld/${process.env.GOOGLEAPIKEY}`)
.send(data.fetchData);

Related

module.export in typescript. import json list

It seems simple, this operates in javascript, but I'm a bit confused about typescript's closest equivalent. I'm trying to use module.exports in the way I know from javascript, passing data the json list data between 3 files.
in javascript the main file basically works as this: -
main.js :
const { mainnet: addresses } = require("./addresses");
const token0 = addresses.tokens.busd;
so, main.ts would be? (i believe main issue is here):
import { mainnet } from "./addresses/index";
token0 = mainnet.tokens.busd;
then typescript index.ts in ./address/index.ts (i believe this functions properly):
import tokensMainnet from './tokens-mainnet.json';
declare var module: any;
// "allowSyntheticDefaultImports" = true
module.exports = {
mainnet: {
tokens: tokensMainnet
}
};
and tokensmainnet.json
{
"busd": "0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56",
"wbnb": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"
}
i can see from the metadata it's functioning:
so I believe the main problem with with importing this module in the main.ts
I've grazed over some sources such as with no luck https://www.typescriptlang.org/docs/handbook/modules.html
in typescript
add
"resolveJsonModule":true
to package.json:
" Allows importing modules with a ‘.json’ extension, which is a common practice in node projects. This includes generating a type for the import based on the static JSON shape." -https://www.typescriptlang.org/tsconfig#resolveJsonModule
so add to main.ts:
import * as data from "./addresses/tokens-mainnet.json"
//...program code...
constructor(){
let tokenAddress = data
console.log(tokenAddress.busd)
}
:)

Typescript import with sending variable to imported files

Didn't found it in documentation. The question is is there anything in typescript like.
file1.js
module.exports = (service) =>
{
service.doSomeCoolStuff();
}
file2.js
const file2 = require('./file2')(service)
I need to send service object to another file and work with it. So is there something like this in typescript? I need to uses exactly this construction. I know it is possible to it with class, but requirement is to use it this way.
TypeScript has modules which support ES imports and exports.
file1.ts
export default (service) => service.doSomeCoolStuff();
file2.ts
import doCoolStuffWithService from './file1';
const file2 = doCoolStuffWithService(service);

Global Import In ES6

I have a large third party library that I need to share between two projects. The project has multiple folders with multiple files that contain multiple exports. Instead of importing these modules like this
import {BaseContainer} from '#company/customproject/src/containers/BaseContainer.js'
I would like to do this
import { BaseContainer } from '#company/customproject'
I know I can manually import all the modules into a single index.js file in the base directory but i am wondering if there is an easier way to do not have import them all explicitly
I know I can manually import all the modules into a single index.js file in the base directory but i am wondering if there is an easier way to do not have import them all explicitly
You should really just create an index.js file and import into that whatever you want to export so that you can control what APIs get exported and to not export private APIs.
That said there is an automated tool that generates an index.js automatically for you:
> npm install -g create-index
> create-index ./src
Which will generate an index.js with all the exports.
As the other answer suggests, you should create an index.js within each directory and explicitly export contents
#company/customproject/index.js
import {BaseContainer, SomeOtherContainer} from './src/containers'
export {
BaseContainer,
SomeOtherContainer
}
#company/customproject/src/containers/index.js
import BaseContainer from './BaseContainer'
import SomeOtherContainer from './SomeOtherContainer'
export {
BaseContainer,
SomeOtherContainer
}
Another option to autoload an entire directory is using require and module.exports to export every scanned file, however. You would likely run into conflicts using both ES6 import/export along with module.exports and default export statements.
#company/customproject/index.js
const fs = require('fs')
const modules = {}
fs.readdirSync(__dirname+'/src/containers').forEach(file => {
file = file.replace('.js', '')
modules[file] = require('./src/containers/'+file)
// map default export statement
if (modules[file].default) {
modules[file] = modules[file].default
}
})
module.exports = modules
Then simply use it in any ES5 or ES6 module
const {BaseContainer} = require('#company/customproject')
or
import {BaseContainer} from '#company/customproject'

Webpack - exporting directory and importing it via path

So I was trying to export a directory with webpack and came up with this script that imports recursively all the files that I need:
// lib1
const req = require.context('./', true, /^(?!.*test.js)^(?!.*Spec.js)^(?!.*__mocks__.*\.js)((.*\.(js\.*))[^.]*$)/)
const modules = {}
req.keys().forEach(key => {
modules[key] = req(key)
})
export default modules
That works fine, I have all modules available to me on subsequent bundles of webpack but it's not exactly what I wanted.
What I really need is a way to export those modules in a way that I can import them using paths instead of grabbing this module object and accessing services via it.
Note:
Apps have ^lib as external module.
webpack#4.1.1
// ex1 what I need:
import theme from 'lib1/services/theme'
// ex2 what I have:
import lib1 from 'lib1'
const theme = lib1.services.theme
Is there a way to achieve this?

Import JSON file in React

I'm new to React and I'm trying to import a JSON DATA variable from an external file. I'm getting the following error:
Cannot find module "./customData.json"
Could some one help me? It works if I have my DATA variable in index.js but not when it's in an external JSON file.
index.js
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import customData from './customData.json';
import Profile from './components/profile';
import Hobbies from './components/hobbies';
class App extends Component {
render() {
return (
<div>
<Profile name={this.props.profileData.name}imgUrl={this.props.profileData.imgURL} />
<Hobbies hobbyList={this.props.profileData.hobbyList}/>
</div>
);
}
}
ReactDOM.render(<App profileData={DATA}/>, document.querySelector('.container'));
hobbies.js
import React, {Component} from 'react';
var Hobbies = React.createClass({
render: function(){
var hobbies = this.props.hobbyList.map(function(hobby, index){
return (<li key={index}>{hobby}</li>);
});
return (
<div>
<h5>My hobbies:</h5>
<ul>
{hobbies}
</ul>
</div>
);
}
});
export default Hobbies;
profile.js
import React from 'react';
var Profile = React.createClass({
render: function(){
return (
<div>
<h3>{this.props.name}</h3>
<img src={this.props.imgUrl} />
</div>
)
}
});
export default Profile
customData.json
var DATA = {
name: 'John Smith',
imgURL: 'http://lorempixel.com/100/100/',
hobbyList: ['coding', 'writing', 'skiing']
}
export default DATA
One nice way (without adding a fake .js extension which is for code not for data and configs) is to use json-loader module. If you have used create-react-app to scaffold your project, the module is already included, you just need to import your json:
import Profile from './components/profile';
This answer explains more.
This old chestnut...
In short, you should be using require and letting node handle the parsing as part of the require call, not outsourcing it to a 3rd party module. You should also be taking care that your configs are bulletproof, which means you should check the returned data carefully.
But for brevity's sake, consider the following example:
For Example, let's say I have a config file 'admins.json' in the root of my app containing the following:
admins.json
[{
"userName": "tech1337",
"passSalted": "xxxxxxxxxxxx"
}]
Note the quoted keys, "userName", "passSalted"!
I can do the following and get the data out of the file with ease.
let admins = require('~/app/admins.json');
console.log(admins[0].userName);
Now the data is in and can be used as a regular (or array of) object.
With json-loader installed, you can use
import customData from '../customData.json';
or also, even more simply
import customData from '../customData';
To install json-loader
npm install --save-dev json-loader
Simplest approach is following
// Save this as someJson.js
const someJson = {
name: 'Name',
age: 20
}
export default someJson
then
import someJson from './someJson'
React 17 created from create-react-app, importing json just work by default.
import config from './config.json'
The solution that worked for me is that:-
I moved my data.json file from src to public directory.
Then used fetch API to fetch the file
fetch('./data.json').then(response => {
console.log(response);
return response.json();
}).then(data => {
// Work with JSON data here
console.log(data);
}).catch(err => {
// Do something for an error here
console.log("Error Reading data " + err);
});
The problem was that after compiling react app the fetch request looks for the file at URL "http://localhost:3000/data.json" which is actually the public directory of my react app. But unfortunately while compiling react app data.json file is not moved from src to public directory. So we have to explicitly move data.json file from src to public directory.
Please store your JSON file with the .js extension and make sure that your JSON should be in same directory.
// rename the .json file to .js and keep in src folder
Declare the json object as a variable
var customData = {
"key":"value"
};
Export it using module.exports
module.exports = customData;
From the component that needs it, make sure to back out two folders deep
import customData from '../customData';
In current react build you simply import and use:
import jsonData from 'path/to/myJson.json'
try with export default DATA or module.exports = DATA
there are multiple ways to do this without using any third-party code or libraries (the recommended way).
1st STATIC WAY: create a .json file then import it in your react component example
my file name is "example.json"
{"example" : "my text"}
the example key inside the example.json can be anything just keep in mind to use double quotes to prevent future issues.
How to import in react component
import myJson from "jsonlocation";
and you can use it anywhere like this
myJson.example
now there are a few things to consider. With this method, you are forced to declare your import at the top of the page and cannot dynamically import anything.
Now, what about if we want to dynamically import the JSON data? example a multi-language support website?
2 DYNAMIC WAY
1st declare your JSON file exactly like my example above
but this time we are importing the data differently.
let language = require('./en.json');
this can access the same way.
but wait where is the dynamic load?
here is how to load the JSON dynamically
let language = require(`./${variable}.json`);
now make sure all your JSON files are within the same directory
here you can use the JSON the same way as the first example
myJson.example
what changed? the way we import because it is the only thing we really need.
I hope this helps.
var langs={
ar_AR:require('./locale/ar_AR.json'),
cs_CZ:require('./locale/cs_CZ.json'),
de_DE:require('./locale/de_DE.json'),
el_GR:require('./locale/el_GR.json'),
en_GB:require('./locale/en_GB.json'),
es_ES:require('./locale/es_ES.json'),
fr_FR:require('./locale/fr_FR.json'),
hu_HU:require('./locale/hu_HU.json')
}
module.exports=langs;
Require it in your module:
let langs=require('./languages');
regards
This worked well in React 16.11.0
// in customData.js
export const customData = {
//json data here
name: 'John Smith',
imgURL: 'http://lorempixel.com/100/100/',
hobbyList: ['coding', 'writing', 'skiing']
}
// in index.js
import { customData } from './customData';
// example usage later in index.js
<p>{customData.name}</p>
My friends, if you are using React and TypeScript, just do these steps and DONE!
In the tsconfig.json add these 2 new lines:
// tsconfig.json
{
"compilerOptions": {
// ... other options
"esModuleInterop": true,
"resolveJsonModule": true
}
}
Import your json:
import yourJSON from "./data/yourJSON.json"
Something that worked for me was to simply place the JSON file in the public folder. You can simply import in any js using
brain.loadData("exampleFile.json");
It is as simple as that I guess. Definitely worth a try :D

Categories