Manage Rails credentials on lib installed with Yarn - ruby-on-rails

I have installed Algolia places in rails with yarn. I am trying to add the api key to rails credentials.
I am importing into application.js with a places.js file:
'use strict';
import places from 'places.js';
import placesAutocompleteDataset from 'places.js/autocompleteDataset';
$(document).on('turbolinks:load', function() {
var placesAutocomplete = places({
appId: 'xxxxxxxx',
apiKey: 'xxxxxxxx',
container: document.querySelector('#user_street_address'),
templates: {
value: function(suggestion) {
return suggestion.name;
}
}
}).configure({
type: 'address'
});
placesAutocomplete.on('change', function resultSelected(e) {
document.querySelector('#user_state').value = e.suggestion.administrative || '';
document.querySelector('#user_city').value = e.suggestion.city || '';
document.querySelector('#user_zipcode').value = e.suggestion.postcode || '';
document.querySelector('#user_country').value = e.suggestion.country || '';
});
});
I have tried to add a initializers in /config/initializers/algoliasearch.rb
AlgoliaSearch.configuration = {
application_id: Rails.application.credentials.algolia[:applicationId],
api_key: Rails.application.credentials.algolia[:apiKey],
# uncomment to use backend pagination
# pagination_backend: :will_paginate
}
but I receive a uninitialized constant error
How can I secure the credentials ?

You would have to use ERB interpolation if you want to use Rails encrypted secrets.
But its really a very pointless endeavor as the credentials are passed to the client in cleartext. There are no secrets in the browser.
Instead you can just pass them as ENV variables to webpack.

Related

"process is not defined" in gatsby-browser?

I'm trying to insert an environment variable "GATSBY_EX_ENV" inside a window property to make it available to external scripts.
and GATSBY_EX_ENV is defined in my environment files alongside numerous other env variables which are accessed at runtime within React components. So I know it's declared correctly and that our env variables are generally working.
Right now in my gatsby-browser.js I am doing this:
export const onClientEntry = () => {
window.onload = () => {
var EXT = location.host
.split('.')
.filter(x => x !== 'www' && x && x !== DOMAIN && x !== 'com')[0];
// additional parsing
window._external.properties = { env: EXT };
}
}
This does work, but it's clunky and brittle. I want to replace that URL parsing with:
window._external.properties = { env: process.env.GATSBY_EX_ENV }
But when I do, my local develop site fails to load with the error "process is not defined". Should I be placing this code in a different method?

Error when setting up password reset with Parse Server

I am using Parse Server hosted on Heroku with mongoDB. I am struggling to get the password reset function working. I have followed the instructions and added the below code to index.js. Once this code is added, when the app launches or I try to send an email I get this error: JSON text did not start with array or object and option to allow fragments not set.
I know that this means the server cannot parse the data back but I'm totally unsure how to fix this. Any help is much appreciated!
var express = require('express');
var ParseServer = require('parse-server').ParseServer;
var path = require('path');
var databaseUri = process.env.DATABASE_URI || process.env.MONGODB_URI;
if (!databaseUri) {
console.log('DATABASE_URI not specified, falling back to localhost.');
}
var api = new ParseServer({
databaseURI: databaseUri || 'MY_DATABASE_URI',
cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
appId: process.env.APP_ID || 'MY_APP_ID',
masterKey: process.env.MASTER_KEY || '', //Add your master key here. Keep it secret!
serverURL: process.env.SERVER_URL || 'MY_SERVER_URL', // Don't forget to change to https if needed
liveQuery: {
classNames: ["Posts", "Comments"] // List of classes to support for query subscriptions
}
verifyUserEmails: true,
//The public URL of your app.
//This will appear in the link that is used to verify email addresses and reset passwords.
//Set the mount path as it is in serverURL
publicServerURL: 'MY_SERVER_URL_FROM_HEROKU',
// Your apps name. This will appear in the subject and body of the emails that are sent.
appName: 'MY_APP_NAME',
// The email adapter
emailAdapter: {
module: 'parse-server-simple-mailgun-adapter',
options: {
// The address that your emails come from
fromAddress: 'MY_MAILGUN_DOMAIN',
// Your domain from mailgun.com
domain: 'MY_MAILGUN_DOMAIN',
// Your API key from mailgun.com
apiKey: 'MY_API_KEY_FROM_MAILGUN',
}
}
});
// Client-keys like the javascript key or the .NET key are not necessary with parse-server
// If you wish you require them, you can set them as options in the initialization above:
// javascriptKey, restAPIKey, dotNetKey, clientKey
var app = express();
// Serve static assets from the /public folder
app.use('/public', express.static(path.join(__dirname, '/public')));
// Serve the Parse API on the /parse URL prefix
var mountPath = process.env.PARSE_MOUNT || '/parse';
app.use(mountPath, api);
// Parse Server plays nicely with the rest of your web routes
app.get('/', function(req, res) {
res.status(200).send('I dream of being a website. Please star the parse-server repo on GitHub!');
});
// There will be a test page available on the /test path of your server url
// Remove this before launching your app
app.get('/test', function(req, res) {
res.sendFile(path.join(__dirname, '/public/test.html'));
});
var port = process.env.PORT || 1337;
var httpServer = require('http').createServer(app);
httpServer.listen(port, function() {
console.log('parse-server-example running on port ' + port + '.');
});
// This will enable the Live Query real-time server
ParseServer.createLiveQueryServer(httpServer);
You're missing a comma after livequery:{...}, before setting verifyUserEmails. Little harder to tell since the block you added for e-mails isn't properly indented.

Can the environmental keys that Parse Server is Using be verified inside the client app?

I was wondering if/how can the Parse-Server environmental variables be verified inside a client IOS App.
For those of us that are yet uncomfortable with backend systems, it would be useful to be able to validate via the client side during testing that the backend Parse-Server is actually using the correct Environmental Keys.
If you are testing the keys to setup parse-server such as appId, clientKey, masterKey, you can implement a verify cloud code.
Once you use appId (or you have set clientKey), you can call this function. Otherwise, you will get errors. You cannot use MasterKey in client-sdk. If you still want to test it, you can implement a rest api with masterKey on your client. But masterKey should not appear in client side, you should avoid user trigger this, or someone may get your masterKey.
Parse.Cloud.define("verify", function(request, response) {
if(request.master==true){
response.success(true);
}else{
response.error(new Error('MasterKey not matched'));
}
});
Edited
By implement a globalConfig obj, verify it as you wish.
Here is a sample.
globalConfig.js
var globalConfig = {};
globalConfig.verify = function(key) {
return globalConfig.keys.testKey==key;
}
module.exports = globalConfig;
index.js (partial)
var globalConfig = require('./globalConfig.js');
var initObj = {
databaseURI: databaseUri || 'mongodb://localhost:27017/dev',
cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
appId: process.env.APP_ID || 'myAppId',
masterKey: process.env.MASTER_KEY || '', //Add your master key here. Keep it secret!
serverURL: process.env.SERVER_URL || 'http://localhost:1337/parse', // Don't forget to change to https if needed
liveQuery: {
classNames: ["Posts", "Comments"] // List of classes to support for query subscriptions
},
testKey: "this is test"
}
var api = new ParseServer(initObj);
globalConfig.keys = initObj;
and then you can use globalConfig.verify() to check your keys
a cloud code example
var globalConfig = require('../globalConfig.js');
Parse.Cloud.define('verify', function(req, res) {
res.success(globalConfig.verify(req.params.testKey));
});
or you can use express post
app.post('/test', function(req, res) {
//verify and response
})

Parse.Cloud.afterSave for sending push notifications not working from Heroku server

I did the migration, from Parse to Heroku and everything went smooth. At this point I didn't have any cloud code or push notifications set up on Parse. When I was done with the migration I begin to implement cloud code to handle push notification every time I save a new text message, but the Parse.Cloud.afterSave method is not running. I know main.js is working because if I implement
Parse.Cloud.define('hello', function(req, res) {
res.success('Hi');
});
I get "Hi" return to my console in Xcode, but for some reason Parse.Cloud.afterSave does nothing. I also know my Parse.Cloud.afterSave code is correct because it's that same code I use on another app through parse though. What am I missing?
Here in my index.js file
var express = require('express');
var ParseServer = require('parse-server').ParseServer;
var path = require('path');
var databaseUri = process.env.DATABASE_URI || process.env.MONGOLAB_URI;
if (!databaseUri) {
console.log('DATABASE_URI not specified, falling back to localhost.');
}
var api = new ParseServer({
databaseURI: databaseUri || '',
cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
appId: process.env.APP_ID || '',
masterKey: process.env.MASTER_KEY || '',
fileKey: 'XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', // file key from parse
serverURL: process.env.SERVER_URL || '',
push: {
ios: {
pfx: '/Users/alexcruz/Desktop/Certificates.p12', // The filename of private key and certificate in PFX or PKCS12 format from disk
bundleId: 'com.daps.DapsPush', // The bundle identifier associate with your app
production: false // Specifies which environment to connect to: Production (if true) or Sandbox
}
}
});
var app = express();
// Serve static assets from the /public folder
app.use('/public', express.static(path.join(__dirname, '/public')));
// Serve the Parse API on the /parse URL prefix
var mountPath = process.env.PARSE_MOUNT || '/parse';
app.use(mountPath, api);
// Parse Server plays nicely with the rest of your web routes
app.get('/', function(req, res) {
res.status(200).send('Make sure to star the parse-server repo on GitHub!');
});
// There will be a test page available on the /test path of your server url
// Remove this before launching your app
app.get('/test', function(req, res) {
res.sendFile(path.join(__dirname, '/public/test.html'));
});
var port = process.env.PORT || 1337;
var httpServer = require('http').createServer(app);
httpServer.listen(port, function() {
console.log('parse-server-example running on port ' + port + '.');
});
// This will enable the Live Query real-time server
ParseServer.createLiveQueryServer(httpServer);
Here is my main.js file
//Push Notification for messages that are received
Parse.Cloud.afterSave("MXTMessage", function(request) {
var messageText = request.object.get('message');
var usersReceived = request.object.get('receiver');
var currentUser = Parse.User.current();
var pushQuery = new Parse.Query(Parse.Installation);
pushQuery.equalTo('user', usersReceived);
pushQuery.notEqualTo('user', currentUser);
Parse.Push.send({
where: pushQuery, // Set our Installation query
data: {
alert: "New message: " + messageText
}
}, {
success: function() {
// Push was successful
},
error: function(error) {
throw "Got an error " + error.code + " : " + error.message;
}
});
});
Thank you
As I am not allowed to comment, I'm going to have to put this in an answer, but just treat it as a comment:
Did you verify the function itself is actually never being called e.g. by adding a console.log at the beginning of the function, or could it be that push itself is not working (you can check that by sending pushes via REST API Calls)? For example, push seems to be broken in parse-server 2.2.0, I had to downgrade to 1.6.0 to get it working.
Workaround could be to create a cloud code function for sending the push and have this function explicitly called by the clients after the message has been saved on the server.
Also you should check this: https://github.com/ParsePlatform/parse-server/issues/301 as you are using Parse.User.current() in your code.
Also, I get the impression that parse-server is not really stable at this time. I experience many bugs using parse-server and Heroku that the app running on parse.com does not have.

Gulp build with browserify environment variable

I'm looking to include either an environment variable or file that my modules can access for conditional flow.
// contains env build specific data
// or value 'develop' || 'production'
var env = require('config');
I know I can access the CL arguments with yargs which is great, but I can't seem to find a way to get arguments into my browserify build.
var bundleStream = {
cache: {},
packageCache: {},
fullPaths: false,
entries: [filename],
extensions: config.extensions,
debug: config.debug,
paths: ['./node_modules', './app/js/'],
require: ['jquery', 'lodash']
};
var bundle = function() {
bundleLogger.start(filename);
return bundleStream
.bundle()
.on('error', handleErrors)
.pipe(source(filename.replace('-app', '-bundle')))
.pipe(gulp.dest(process.cwd()))
.on('end', reportFinished)
.pipe(browserSync.reload({
stream: true
}));
};
You could create a config.json file dynamically, and then require it in your modules:
var fs = require('fs');
var gutil = require('gulp-utils');
gulp.task('create-config', function(cb) {
fs.writeFile('config.json', JSON.stringify({
env: gutil.env.env,
tacos: 'delicious'
}), cb);
});
gulp.task('browserify', ['create-config'], function() {
//...
});
In your modules:
var config = require('./config.json');
if (config.env === 'production') {
//...
}
And on the command line:
gulp --env=production

Resources