Using Crypto.js in meteor - javascript

I am trying to include some crypto.js libraries in a meteor js app (meteor version 0.6.4.1).
http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-sha256.js
http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/enc-base64-min.js
When I copy and paste the contents into the server/main.js file it works fine, but this makes it very un-readable.
When I put the libraries in separate files in the server directory (I also tried placing them in the lib directory) I get the error ReferenceError: CryptoJS is not defined.
gist of server/main.js:
Meteor.methods({
encrypt:function(bundleID){
return CryptoJS.HmacSHA256(string, 'something');
}
});
I also tried changing the first line of the hmac-sha256.js file from
var CryptoJS=CryptoJS||function(h,s){...
to:
CryptoJS=CryptoJS||function(h,s){...
to make it global, but this also did not work. How do I include this library properly?

In your application dir create folder 'packages/cryptojs' and put there files:
hmac-sha256.js
enc-base64-min.js
package.js
packages / cryptojs / package.js:
Package.describe({
summary: "CryptoJS"
});
Package.on_use(function (api, where) {
api.add_files(['hmac-sha256.js'], ['client','server']);
api.add_files(['enc-base64-min.js'], ['client','server']);
});
You need to modify hmac-sha256.js by changing beginning of line 7 from:
var CryptoJS=CryptoJS||function(h,s){
to:
CryptoJS=function(h,s){
After that, you can use it:
var hash = CryptoJS.HmacSHA256("Message", "secret");
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
console.log(hashInBase64)
Example source

I followed as parhelium's guide, but still not work, then I found new way to fix this issue:
Just replace line 7 in hmac-sha512.js to this one to globalize CryptoJS object:
this.CryptoJS=this.CryptoJS
Fix the same for other cryptojs. To use with Base64, you must make sure the base64.js is loaded after other libraries.

The reason this is happening is due to the variable scoping in meteor. Try putting the cryptojs library files in /server/compatibility. This way the cryptojs library can be accessed in other files.
You could also get it working without putting it in /compatibility by removing the var used in the cryptojs source files. The thing is if you do this its harder to keep the files up to date.

Related

Browserify: Uncaught error when requiring js file by path created from string concatenation

I am using browesify for client side app. I have files maps.js and directions.js sitting besides my index.js file, and inside my index.js, I have a function getPageName() which returns the name of the file that I should "require". When I try to do
var pageName = getPageName();
var page;
if (pageName === 'maps') {
page = require('./maps');
} else if (pageName === 'directions') {
page = require('./directions');
}
it works fine. But when I instead try to use following trick to minimize my code,
var pageName = getPageName();
var page = require('./' + pageName);
I get error Uncaught Error: Cannot find module './maps' in console log in Chrome. Why does it not work when I use string concatenation but works when I use pass the path explicitly?
That is a limitation of Browserify and similar type libraries. In order to do the require() the library has to examine the js code as a string, and determine file paths before the code is run. This means file paths have to be static in order for it to be picked up.
https://github.com/substack/node-browserify/issues/377
Browserify can only analyze static requires. It is not in the scope of
browserify to handle dynamic requires

How to create QUnit tests with reference to another class?

I'm trying to add unit testing for JavaScript into my web site. I use VS2013 and my project is an ASP.NET web site.
Based on recommendations (http://www.rhyous.com/2013/02/20/creating-a-qunit-test-project-in-visual-studio-2010/) I've done so far:
Created new ASP.NET app
Imported QUnit (using NuGet)
Into "Scripts" added links to js-file in my original web site (files PlayerSkill.js - containts PlayerSkill class and trainings.js - contains Trainer and some other classes)
Created new folder "TestScripts"
Added TrainingTests.js file
Wrote simple test:
test( "Trainer should have non-empty group", function () {
var group = "group";
var trainer = new Trainer(123, "Name123", group, 123);
EQUAL(trainer.getTrainerGroup(), group);
});
Notice: my trainings.js file among others contains
function Trainer(id, name, group, level) {
...
var _group = group;
this.getTrainerGroup = function () { return _group ; }
};
When I execute my test I see error: Trainer is not defined.
It looks like reference to my class is not recognized. I feel like linking file is not enough, but what did I miss?
Please help add reference to the original file with class and run unit test.
Thank you.
P.S. Question 2: Can I add reference to 2 files (my unit test will require one more class which is in another file)? How?
You should add all the relevant logic of your application to your unit testing file so they all execute before you run your tests
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>QUnit Test Results</title>
<link rel="stylesheet" href="/Content/qunit.css">
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="/Scripts/qunit.js"></script>
<script src="/Scripts/PlayerSkill.js"></script>
<script src="/Scripts/trainings.js"></script>
<script src="/TestScripts/TrainingTests.js"></script>
</body>
</html>
You should not use linked files because they will not exist physically in the script folder.
If you really want to use them you should let the Visual Studio intellisense resolve the physical path of the file like this.
Type the script tag <script src=""></script>
Place the cursor inside the quotes in the src attribute and press CTRL + SPACE
Search your files and let the resolved path untouched
If your project location changes you must update the linked files and also the script references.
{Edit1}
Solution 2:
You could also use an MVC Controller and a Razor View to create your unit testing page and the linked files will work as expected with the only issue that you will have an extra controller in your project but this is not bad at all if for example you want to test the loading of content using ajax that is by default blocked by the browser if they are run from a local file.
Solution 3:
You can also setup a new MVC project just for your javascript unit testing just as you usually setup a new project for any server side code and this will help to prevent your testing to interfere with your production code
{Edit 2}
Solution 4:
As part of the javascript ecosystem you could use grunt or gulp to automate the copy of your scripts from anywhere to your project before running the tests. You could write a gulpfile.js like this
var sourcefiles = [/*you project file paths*/];
gulp.task('default', function () {
return gulp.src(sourcefiles).pipe(gulp.dest('Scripts'));
});
And then run it opening a console and running the command gulp or gulp default
Looks like trainings.js is not defined when calling TrainingTests.js . See this question for more details regarding why this happens! Once that is fixed it does work. And yes similar to trainings.js you can have any number of files in any folder as long as you reference them properly. I have created a sample fiddle accessible # http://plnkr.co/edit/PnqVebOzmPpGu7x2qWLs?p=preview
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="http://code.jquery.com/qunit/qunit-1.18.0.js"></script>
<script src="trainings.js"></script>
<script src="TrainingTests.js"></script>
</body>
In my case I wanted to run my tests from within my ASP.NET web application, and also on a CI server. In addition to the other information here I needed the following, otherwise I experienced the same error as the OP on my CI server:
Add one or more require() calls to test scripts.
Set the NODE_PATH environment variable to the root of my application.
Example of require()
Within my test scripts I include a requires block, the conditional allows me to use this script from a web browser without needing to adopt a third-party equivalent such as requirejs (which is convenient.)
if (typeof(require) !== 'undefined') {
require('lib/3rdparty/dist/3p.js');
require('js/my.js');
require('js/app.js');
}
Example of setting NODE_PATH
Below, 'wwwroot' is the path of where /lib/ and other application files are located. My test files are located within /tests/.
Using bash
#!/bin/bash
cd 'wwwroot'
export NODE_PATH=`pwd`
qunit tests
Using powershell
#!/usr/bin/pwsh
cd 'wwwroot'
$env:NODE_PATH=(pwd)
qunit tests
This allowed me to run tests both within my ASP.NET web application, and also from a CI server using a script.
HTH.
If you're wondering how to make your tests see your code when running from command line (not from browser!), here is a bit expanded version of Shaun Wilson's answer (which doesn't work out-of-the-box, but contains a good idea where to start)
Having following structure:
project
│ index.js <--- Your script with logic
└───test
tests.html <--- QUnit tests included in standard HTML page for "running" locally
tests.js <--- QUnit test code
And let's imagine that in your index.js you have following:
function doSomething(arg) {
// do smth
return arg;
}
And the test code in tests.js (not that it can be the whole content of the file - you don't need anything else to work):
QUnit.test( "test something", function( assert ) {
assert.ok(doSomething(true));
});
Running from command line
To make your code accessible from the tests you need to add two things to the scripts.
First is to explicitly "import" your script from tests. Since JS doesn't have sunch a functionality out-of-the box, we'll need to use require coming from NPM. And to keep our tests working from HTML (when you run it from browser, require is undefined) add simple check:
// Add this in the beginning of tests.js
// Use "require" only if run from command line
if (typeof(require) !== 'undefined') {
// It's important to define it with the very same name in order to have both browser and CLI runs working with the same test code
doSomething = require('../index.js').doSomething;
}
But if index.js does not expose anything, nothing will be accessible. So it's required to expose functions you want to test explicitly (read more about exports). Add this to index.js:
//This goes to the very bottom of index.js
if (typeof module !== 'undefined' && module.exports) {
exports.doSomething = doSomething;
}
When it's done, just type
qunit
And the output should be like
TAP version 13
ok 1 Testing index.js > returnTrue returns true
1..1
# pass 1
# skip 0
# todo 0
# fail 0
Well, due to help of two answers I did localize that problem indeed was in inability of VS to copy needed file into test project.
This can be probably resolved by multiple ways, I found one, idea copied from: http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml
Solution is simple: add tag dynamically
In order to achieve this, I've added the following code into tag:
<script>
var fileref = document.createElement('script');
fileref.setAttribute("type", "text/javascript");
var path = 'path'; // here is an absolute address to JS-file on my web site
fileref.setAttribute("src", path);
document.getElementsByTagName("head")[0].appendChild(fileref);
loadjscssfile(, "js") //dynamically load and add this .js file
</script>
And moved my tests into (required also reference to jquery before)
$(document).ready(function () {
QUnit.test("Test #1 description", function () { ... });
});
Similar approach also works for pure test files.

gulp: Automatically add version number to request for preventing browser cache

I deploy my project by building source files with gulp right on the server. To prevent caching issues, the best practice could be adding a unique number to request url, see: Preventing browser caching on web application upgrades;
In npm repositories, I couldn't find a tool for automatically adding version number to request. I'm asking if someone has invented such tool before.
Possible implementation could be the following:
I have a file index.html in src/ folder, with following script tag
<script src="js/app.js<!-- %nocache% -->"></script>
During build it is copied to dist/ folder, and comment is replaced by autoincrement number
<script src="js/app.js?t=1234"></script>
You can use gulp-version-number for this. It can add version numbers to linked scripts, stylesheets, and other files in you HTML documents, by appending an argument to the URLs. For example:
<link rel="stylesheet" href="main.css">
becomes:
<link rel="stylesheet" href="main.css?v=474dee2efac59e2dcac7bf6c37365ed0">
You don't even have to specify a placeholder, like you showed in your example implementation. And it's configurable.
Example usage:
const $ = gulpLoadPlugins();
const versionConfig = {
'value': '%MDS%',
'append': {
'key': 'v',
'to': ['css', 'js'],
},
};
gulp.task('html', () => {
return gulp.src('src/**/*.html')
.pipe($.htmlmin({collapseWhitespace: true}))
.pipe($.versionNumber(versionConfig))
.pipe(gulp.dest('docroot'));
});
NOTE:
I can no longer recommend this plugin. It is no longer maintained and there are some issues with it. I created a pull request some time ago, but there is no response from the author.
You can use the gulp-rev module. This will append a version number to the files, the version is a hash of the file content, so it will only change if the file changes.
You then output a manifest file containing the mapping between the file e.g. Scripts.js to Scripts-8wrefhn.js.
Then use a helper function when returning the page content to map the correct values.
I have used the above process. However there's another module gulp-rev-all which is an forked extension of gulp-rev which does a little more, e.g. automatic updating of file references in pages.
Documentation here:
gulp-rev: https://github.com/sindresorhus/gulp-rev
gulp-rev-all: https://www.npmjs.com/package/gulp-rev-all
I worked onto writing an regex, which in use along with gulp-replace works just fine.
Please find the code below. Following is a quick code for the image and css for views files codeigniter framework. But it should work fine for all the kinds of files given the source folder specified correctly.
You may customize the code as per your use.
You can call the tasks altogether, using gulp default or individual task at a time.
'use strict';
var gulp = require('gulp');
var replace = require('gulp-replace');
function makeid() {
return (Math.random() + 1).toString(36).substring(7);
}
gulp.task('versioningCss', () => {
return gulp.src('application/modules/**/views/*.php')
.pipe(replace(/(.*)\.css\?(_v=.+&)*(.*)/g, '$1.css?_v='+makeid()+'&$3'))
.pipe(replace(/(.*)\.css\"(.*)/g, '$1.css?_v='+makeid()+'"$2'))
.pipe(replace(/(.*)\.css\'(.*)/g, '$1.css?_v='+makeid()+'\'$2'))
.pipe(gulp.dest('application/modules'));
});
gulp.task('versioningJs', () => {
return gulp.src('application/modules/**/views/*.php')
.pipe(replace(/(.*)\.js\?(_v=.+&)*(.*)/g, '$1.js?_v='+makeid()+'&$3'))
.pipe(replace(/(.*)\.js\"(.*)/g, '$1.js?_v='+makeid()+'"$2'))
.pipe(replace(/(.*)\.js\'(.*)/g, '$1.js?_v='+makeid()+'\'$2'))
.pipe(gulp.dest('application/modules'));
});
gulp.task('versioningImage', () => {
return gulp.src('application/modules/**/views/*.php')
.pipe(replace(/(.*)\.(png|jpg|jpeg|gif)\?(_v=.+&)*(.*)/g, '$1.$2?_v='+makeid()+'&$4'))
.pipe(replace(/(.*)\.(png|jpg|jpeg|gif)\"(.*)/g, '$1.$2?_v='+makeid()+'"$3'))
.pipe(replace(/(.*)\.(png|jpg|jpeg|gif)\'(.*)/g, '$1.$2?_v='+makeid()+'\'$3'));
});
gulp.task('default', [ 'versioningCss', 'versioningJs', 'versioningImage']);
It looks like you may have quite a few options.
https://www.npmjs.com/package/gulp-cachebust
https://www.npmjs.com/package/gulp-buster
Hope this helps.
You can use
<script type="text/javascript" src="js/app.js?seq=<%=DateTime.Now.Ticks%>"></script>
or
<script type="text/javascript" src="js/app.js?seq=<%=DateTime.Now.ToString("yyyyMMddHHmm") %>"></script>

How to create a snapshot of .js file -> webkit nwjs v8

Can somebody please explain me how to make a snapshot of javascript file in nodewebkit (now known as http://nwjs.io/) aplication.
I found this wiki https://github.com/nwjs/nw.js/wiki/Protect-JavaScript-source-code-with-v8-snapshot
but i cannot find nwsnapshot aplication.
Or where i need to input code (nwsnapshot --extra_code mytest.js mytest.bin) to convert - compile it?
If you cannot find nwsnapshot, then look after nwjc.
To make a snapshot, you'll type under console (replace names accordingly):
nwjc yourjsfiletoprotect.js jshidden.bin
Then, you'll need to import jshidden.bin into your HTML file. You will not achieve this using <script src="jshidden.bin"></script>. That won't work.
You'll achieve this by writing:
<script>
var nw = require('nw.gui');
nw.Window.get().evalNWBin(null, 'jshidden.bin');
</script>
You'd be aware that there are serious limitations when it comes to using nw snapshots.

Minify Scripts/CSS in production mode with node.js

I have a web app that runs in node. All the (client) Javascript/CSS files are not minified at the moment to make it easier to debug.
When I am going into production, I would like to minify these scripts. It would be nice to have something like:
node app.js -production
How do I serve the minified version of my scripts without changing the script tags in my html files? There should be something like: if I am in production, use these 2 minified(combined) scripts, else use all my unminified scripts..
Is this possible? Maybe I am thinking too complicated?
You might be interested in Piler. It's a Node.js module that delivers all the JavaScript (and CSS) files you specify as usual when in debug mode, but concatenated and minified when in production mode.
As a special feature, you can force CSS updates via Socket.io in real-time to appear in your browser (called "CSS Live Updated" in Piler), which is quite awesome :-).
The trick is that inside your template you only have placeholders for the script and link elements, and Piler renders these elements at runtime - as single elements in debug mode, and as a dynamically generated single element in production mode.
This way you can forget about creating concatenated and minified versions of your assets manually or using a build tool, it's just there at runtime, but you always have the separated, full versions when developing and debugging.
you could use 2 separate locations for your static files
Here's some express code:
if (process.env.MODE === "production") {
app.use(express['static'](__dirname + '/min'));
} else {
app.use(express['static'](__dirname + '/normal'));
}
and start node with
MODE=production node app.js
Furthermore, if you don't want to duplicate all your files, you could take advantage of the fact that express static router stops at the first file, and do something like this instead:
if (process.env.MODE === "production") {
app.use(express['static'](__dirname + '/min')); // if minized version exists, serves it
}
app.use(express['static'](__dirname + '/normal')); // fallback to regular files
Using the same name for minimized or not is going to cause problem with browser caching, though.
I want to share my final solution with you guys.
I use JSHTML for Express (enter link description here)
In my main node file I use a special route:
app.get('/**:type(html)', function (req, res, next) {
var renderingUrl = req.url.substring(1, req.url.lastIndexOf("."));
//TODO: Find a better solution
try{
var assetUrl = req.url.substring(req.url.lastIndexOf("/") + 1, req.url.lastIndexOf("."));
var assets = config.getResourceBundle(assetUrl);
assets.production = config.getEnviroment() === "production";
res.locals(assets);
res.render(renderingUrl);
}catch(e){
res.redirect("/");
}
});
As you can see, I get my assets from config.getResourceBundle. This is a simply function:
exports.getResourceBundle = function(identifier){
switch(enviroment){
case "development":
return devConfig.getResourceBundle(identifier);
case "production":
return prodConfig.getResourceBundle(identifier);
default:
return devConfig.getResourceBundle(identifier);
}
}
And finally an example for an asset file collection is here:
exports.getResourceBundle = function (identifier) {
return resourceBundle[identifier];
};
resourceBundle = {
index:{
cssFiles:[
"resources/dev/css/login.css",
"resources/dev/css/logonDlg.css",
"resources/dev/css/footer.css"
],
jsFiles:[
"resources/dev/js/lib/jquery/jquery.183.js",
"resources/dev/js/utilities.js",
"resources/dev/js/lib/crypto.3.1.2.js"
]
},
register:{
cssFiles:[
"resources/dev/css/login.css",
"resources/dev/css/modalDialog.css",
"resources/dev/css/footer.css"
],
jsFiles:[
"resources/dev/js/lib/jquery/jquery.183.js",
"resources/dev/js/utilities.js",
"resources/dev/js/lib/crypto.3.1.2.js",
"resources/dev/js/lib/jquery.simplemodal.js",
"resources/dev/js/xfiles.register.js"
]
}
(...)
I have 2 folders. dev / prod. grunt will copy the minified files into prod/.. and deletes the files from dev/...
And if the NODE_ENV variable is set to production, I will ship the minified versions of my scripts/css.
I think this is the most elegant solution at the moment.
There are build tool plugins for you, may help you gracefully solve this problem:
For Gulp:
https://www.npmjs.org/package/gulp-useref/
For Grunt:
https://github.com/pajtai/grunt-useref
Another Node.js module which could be relevant is connect-cachify.
It doesn't seem to do the actual minification for you, but it does let you serve the minified version in production, or all the original scripts in development, without changing the templates (thanks to cachify_js and cachify_css).
Seems it's not as feature-rich as Piler, but probably a bit simpler, and should meet all the requirements mentioned in the question.

Categories

Resources