Google Spreadsheet: Encrypt cell content with Google Apps Script - javascript

I have a Google Spreadsheet and would like to encrypt the content of a few cells (I do not care which encryption method is being used as long as there is an equivalent decryption method for iOS).
Unfortunately there are no built-in encryption functions in Google Apps Script.
For this reason I would like to use a open source Javascript library like Crypto-JS and sjcl.
How can I use one of these libraries with Google Apps Script?
In the Google Apps Script documentation, I have not found any clue on how to use external JavaScript libraries with my Google Apps Script.

Well I'll say this, because this is the method that I used with Date JS. You can do the following:
Download the source .js file(s).
Open the .js file(s) in a text editor
Copy/paste all code into a new Script Project
here you can "recreate" the original .js files (copy/paste source individually) with the same names
Include the project key of that Script Project as a library of the project in which you want to use those functions.
Even if the projects are open-source you will want to make sure you comply with the licenses of those projects if you are going to use them.
This is basically a small "hack" around not being able to upload .js files into GAS Projects. Assuming that the JS is standard, this method will work with Google's system.
The other option is to simple find a light-weight one- or two-function crypto package, or a single crypto algorithm like AES-128 (taht you are given permission to use, of course). It really depends on how much encryption you want, if you need to reverse the cipher text to get the plain values, etc.
If this is a for some kind of password system, I would recommend using a simple hash. For example:
function stringHash (someString) {
var hash = 0;
if (this.length == 0) return hash;
for (i = 0; i < this.length; i++) {
char = this.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash;
}
return Math.abs(hash); // Personally I don't like negative values, so I abs'd it
}
in which you would ask for a user's password, and if the password hash matched the hash stored in the spreadsheet or wherever, then you would validate. You can use this to simulate logging into a UiApp GUI, for example: store usernames/password hashes in a database and validate a user before loading the "real" app.
However, as Serge mentioned, Spreadsheets will contain revision history of the original value before it was hashed, as well as the value after it was hashed. If you want to avoid this, use ScriptDB.
PS - in addition to this work-around, I'll say that it's not currently possible to "import" a non-GAS code library into your Script Project, unless you manually copy the source file-by-file into your Script Project. There may be a feature request on the Issue Tracker already, if not you can create one and I'll star it.
EDIT: As per request, I've included an open source AES encryption "package" (contains base64 as well, which is nice) in the answer, to act as a reference for others who want to encrypt in GAS. Make sure you follow the author's request, which is to retain his original copyright and link back to the source.
Other than the AES I linked and the simple hash (equivalent to Java's String.hashCode()), whose resource can be found here, there is Crypto-JS as you mentioned in your question and, if you took the time to fully copy/paste all the code (assuming that agrees with the terms of the license - I haven't read it), you could use that by the steps I described in the top half of my answer.
MD5 in Javascript is also an algorithm that you could use. If you use the code in md5.js which is located at the top of the page, you'll have what you need. Again, make sure you're following licensing rules if you use it.
Personally I would probably just use the hash and the base-64 patterns, as most of what you would use this encryption for is probably not incredibly important. AES might take a bit longer to compute - you can probably benchmark it yourself to see if it will cause major problems with triggers running for an extended period of time, but I doubt it would be a problem anyway.
Note: base-64 is 2-way, so is AES. MD5 is a type of hash, and the simple hash function I provided is also (of course) a hash. Hash functions are one-way. So if you need two-way functionality (encrypt/decrypt), then use base-64 or AES. Base-64 is essentially the kid version of AES. And the simple hash function is the kid version of MD5. Keep this in mind :)
Edit again: I'm not familiar with iOS development or its internals, but it seems to me that iOS can at least do some cryptographic operations. You may want to read more into those methods though, because I'm not really sure how you're putting GAS and iOS together; I can't give you any more help in that area unfortunately.

The functions above don't work for me. Here is something what you can copy and paste into google sheets (spreadsheet) script editor
function enc(str) {
var encoded = "";
for (i=0; i<str.length;i++) {
var a = str.charCodeAt(i);
var b = a ^ 123; // bitwise XOR with any number, e.g. 123
encoded = encoded+String.fromCharCode(b);
}
return encoded;
}
This is what you get when you use it =ENC in your spreadsheet
Based on this post here

External libraries can be used by using JavaScript's built in eval() function
(ex. eval(UrlFetchApp.fetch('path/to/library'))).
Of course, the library must have no dependencies for this to work.

Related

Windows tool to decode HTML entities in a file

Is there a command line/batch script tool for Windows that can be used to decode HTML entitles like , ℘, and ‰ to readable UTF-8 text?
I found this web tool (https://mothereff.in/html-entities) that uses javascript that can do just this but I need this done from a Windows batch file. I know of the amazing JREPL.bat utility which incorporates javascript into windows command shell to make regex replacements in files. I just can't find a similar tool for HTML entities conversion.
Edit: To the bright coders out there, I hope you can write a batch tool that can perform HTML entities decoding/encoding to help me and the future readers looking for the same solution. Here are Github pages I think can be of use: https://github.com/mathiasbynens/he https://github.com/mathiasbynens/mothereff.in/tree/master/html-entities
You don't need extensive applications (like JREPL.bat or my own FindRepl.bat) or complicated programs in order to perform a replacement as simple as this one. The small Batch file below is an example that performs a replacement of 3 HTML entities:
#set #a=0 // & cscript //nologo //E:JScript "%~F0" < input.txt & goto :EOF
var rep = new Array();
rep["©"] = "\u00A9";
rep["팆"] = "\uD306";
rep["☃"] = "\u2603";
var f = new ActiveXObject("Scripting.FileSystemObject").CreateTextFile("output.txt", true, true);
f.Write(WScript.Stdin.ReadAll().replace(/©|팆|☃/g,function (A) {return rep[A]}));
f.Close();
input.txt:
Foo © bar 팆 baz ☃ qux
output.txt:
Foo © bar 팆 baz ☃ qux
You only need to add as many character equivalences as you want to convert...
It is trivial to incorporate JScript into a batch file, so you could easily write your own custom hybrid JScript/batch script that incorporates the he.js found at https://github.com/mathiasbynens/he.
But it is even simpler to use the JREPL.BAT tool that you already mentioned. You can use the /JLIB option to load the he.js code, thus making all of the he (html-entities) functionality accessible to JREPL.
Here is a trivial example that decodes test.txt, overwriting the original file.
jrepl "^.*" "he.decode($0)" /jlib "he.js" /f test.txt /o -
This isn't the most efficient way to do it, but it is probably plenty fast enough, and it sure is convenient.
Here is another example that encodes every character in test.txt (including newlines), writing the result to out.txt
jrepl "^[\s\S]*" "he.encode($0,{encodeEverything:true})" /m /j /jlib he\he.js /f test.txt /o out.txt
You should study all the documentation for both he and JREPL to discover all the possibilities.
The regex portion in the examples might seem to be more of a hindrance then help. But it is easy to envision how it might be useful to selectively encode only portions of your input text. Or you could use the JREPL /T option to use different encoding options for different sections of text.

iPython/Jupyter Notebook: How to Embed Interactive Graph Using Desmos API?

I've recently switched from taking notes for my Calculus II course with the pen-and-paper system to using Jupyter (formerly known as iPython) notebooks. What a difference!
Anyway, as someone who learns best through visual presentations, I would really like to embed some interactive Desmos graphs in my notebooks (for anyone who is not familiar with Desmos, it is an incredibly powerful, yet easy-to-use, web-based graphing calculator).
Unfortunately, the iPython/Jupyter notebook security model prevents the execution of JavaScript embedded in Markdown cells. The HTML Sanitization library (Google Caja, I believe) strips any HTML tags and JavaScript code you put into Markdown cells.
According to a note in the security model docs, support for some sort of mechanism for allowing HTML/CSS for notebook theming is planned. But the note makes no mention of JavaScript support.
I realize cross-site scripting is a serious problem and one that is difficult to defend against, but is there really no means to loosen the security constraints for notebook authors? Perhaps in the future it might be possible to add a configuration option to the notebook metadata (which can be edited from within a notebook session) to specify a list of allowable tags.
In the meantime, does anyone know of a work-around, hack, or other method for embedding output from a third-party API using JavaScript in Markdown cells within a notebook?
If one were to print the appropriate HTML and JavaScript code using Python within a Python cell, would that avoid these restrictions? Maybe I should write a Python wrapper for the Desmos API...
You can always use an interact from IPython widgets
from IPython.html.widgets import *
import numpy as np
import matplotlib.pyplot as plt
import math
def linear(w,x,b):
return w*x + b
def logistic(z):
return 1/(1+math.e**(-z))
def plt_logistic(a, b):
x = np.linspace(-20,20, 100)
h = linear(a,x,b)
y = logistic(h)
plt.ylim(-5,5)
plt.xlim(-5,5)
plt.plot(x,h)
plt.plot(x,y)
plt.grid()
plt.show()
interact(plt_logistic, a = (-10,10,0.1), b = (-10,10,0.1))
Here is how to embed Desmos in Jupyter using jp_proxy widgets:
Please see https://github.com/AaronWatters/jp_proxy_widget
-- this code is based on the quick start example: https://www.desmos.com/api/v1.2/docs/index.html
I think there are several ways to make it
use iframe
use raw html display, which may need you write
some wrapper first to make it reuseable
use some 3-party lib: mpld3, plot.js, here is a list
use some other type 3-party lib: IPython-Dashboard

Javascript preprocessor to replace variable reference during build

Is there a way to substitute variables in javascript files, with a preprocessor during build process. I uses grunt, usemin, uglifyjs (part of yeoman stack).
I currently refer to url from a global javascript object. For example,
my.url = {
book: {
get : '/my/book/{id},
new: '/my/book'
}
}
in my program, I may refer the url as my.url.book.get, etc. The intention is
do not want the url string spread across the program, as any change during development make it hard to refactor.
url may generate based on the server API, and don't want to duplicate in client.
Now, once I am happy with the development, I like to preprocess all the javascript file to substitute all these references to actual url string. Intention is to avoid loading an extra file with all the url (may the user only need few of the url).
is there any tool, similar to html templating package, to process the javascript and replace all the variables. I prefer if it works with grunt/yeoman stack.
You can do that with grunt-replace It allows for all kinds of string substitutions in text files. I use it to sync version numbers in bower.json, package.json etc, but obviously you can use it for source file value substitutions as well.
That said, in your case I'd definitely opt for a more dynamic solution with env variables, with for instance grunt-env.
Try #Builder https://github.com/electricimp/Builder
Little example
in config.js:
#set apiEndpoint "https://somesite.com/api/v1"
then:
#include once "config.js"
let url = "#{apiEndpoint}"

Embedding Javascript (file): what means "filename.js?v=2.0.4"? [duplicate]

When I saw many sites' source code, parameters were passed to the linking file (CSS/JavaScript).
In the Stack Overflow source, I got
<script type="text/javascript" src="http://sstatic.net/js/master.js?v=55c7eccb8e19"></script>
Why is master.js?v=55c7eccb8e19 used?
I am sure that JavaScript/CSS files can't get the parameters.
What is the reason?
It is usually done to prevent caching.
Let's say you deploy version 2 of your new application and you want to cause the clients to refresh their CSS, you could add this extra parameter to indicate that it should re-request it from the server. Of course there are other approaches as well, but this is pretty simple.
As the others have said, it's probably an attempt to control caching, although I think it's best to do so by changing the actual resource name (foo.v2.js, not foo.js?v=2) rather than a version in the query string. (That doesn't mean you have to rename files, there are better ways of mapping that URL to the underlying file.) This article, though four years old and therefore ancient in the web world, is still a quite useful discussion. In it, the author claims that you don't want to use query strings for versions because:
...According the letter of the HTTP caching specification, user agents should never cache URLs with query strings. While Internet Explorer and Firefox ignore this, Opera and Safari don’t...
That statement may not be quite correct, because what the spec actually says is
...since some applications have traditionally used GETs and HEADs with query URLs (those containing a "?" in the rel_path part) to perform operations with significant side effects, caches MUST NOT treat responses to such URIs as fresh unless the server provides an explicit expiration time...
(That emphasis at the end is mine.) So using a version in the query string may be fine as long as you're also including explicit caching headers. Provided browsers implement the above correctly. And proxies do. You see why I think you're better off with versions in the actual resource locator, rather than query parameters (which [again] doesn't mean you have to constantly rename files; see the article linked above for more). You know browsers, proxies, etc. along the way are going to fetch the updated resource if you change its name, which means you can give the previous "name" a never-ending cache time to maximize the benefit of intermediate caches.
Regarding:
I am sure that Js/CSS files can't get the parameters.
Just because the result coming back is a JavaScript or CSS resource, it doesn't mean that it's a literal file on the server's file system. The server could well be doing processing based on the query string parameters and generating a customized JavaScript or CSS response. There's no reason I can't configure my server to route all .js files to (say) a PHP handler that looks at the query string and returns something customized to match the fields given. Thus, foo.js?v=2 may well be different from foo.js?v=1 if I've set up my server to do so.
That's to avoid the browser from caching the file. The appending version name has no effect on the JavaScript file, but to the browser's caching engine it looks like a unique file now.
For example, if you had scripts.js and the browser visits the page, they download and cache (store) that file to make the next page visit faster. However, if you make a change the browser may not recognize it until the cache has expired. However, scripts.js?v2 now makes the browser force a re-fetch because the "name's changed" (even though it hasn't, just the contents have).
A server-side script generating the CSS or JavaScript code could make use of them, but it is probably just being used to change the URI when the the content of the file changes so that old, cached versions won't cause problems.
<script type="text/javascript">
// front end cache bust
var cacheBust = ['js/StrUtil.js', 'js/protos.common.js', 'js/conf.js', 'bootstrap_ECP/js/init.js'];
for (i=0;i<cacheBust.length;i++){
var el = document.createElement('script');
el.src = cacheBust[i]+"?v=" + Math.random();
document.getElementsByTagName('head')[0].appendChild(el);
}
</script>
This is to force the browser to re-cache the .js file if there has been any update.
You see, when you update your JS on a site, some browsers may have cached the old version (to improve performace). Sicne you want them to use your new one, you can append something in the query-field of the name, and voíla! The browser re-fetches the file!
This applies to all files sent from the server btw.
Since javascript and css files are cached by the client browser, so we append some numeric values against their names in order to provide the non-cached version of the file
"I am sure that JavaScript /CSS files can't get the parameters"
function getQueryParams(qs) {
qs = qs.split("+").join(" ");
var params = {},
tokens, re = /[?&]?([^=]+)=([^&]*)/g;
while (tokens = re.exec(qs)) {
params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
}
return params;
}
This is referred to as Cache Busting.
The browser will cache the file, including the querystring. Next time the querystring is updated the browser will be forced to download the new version of the file.
There are various types of cache-busting, for example:
Static
Date/Time
Software Version
Hashed-Content
I've wrote an article on cache busting previously which you may find useful:
http://curtistimson.co.uk/front-end-dev/what-is-cache-busting/

Get access to Stackoverflow's auto-suggest tagging system?

Is there anyway to get access to stackoverflow's awesome tagging system? I would like to borrow Stack's awesome auto-suggest and tag mini-explanation boxes for my own site. Obviously, I can use the jQuery UI auto-suggest for tags but I would really like to also include the cool little tag descriptions as well. If not, can someone tell me where all these explanation/descriptions came from so that I can implement a similar system?
tageditornew.js
Line 308:
$.get("/filter/tags", {q: a,newstyle: !0}, "json").done(function(c) {
C["t_" + a] = c;
StackExchange.helpers.removeSpinner();
b(c)
})
This might help you out!
It turns out that,
the API url is this:
https://stackoverflow.com/filter/tags?q=STRING&newstyle=BOOLEAN
q - Query text.
newstyle - Require new style or not. Result in new style will be returned in JSON with additional information such as synonyms and excerpt.
DEMO: http://jsfiddle.net/DerekL/bXXb7/ (with Cross Domain Requests jQuery plguin)
For example:
https://stackoverflow.com/filter/tags?q=htm
would give you:
"html|99829\nhtml5|16359\nxhtml|4143\nhtml-parsing|1461\nhtml-lists|1328\nhtml5-video|949"
where 99829 is the amount of questions. It took me 15 minutes looking at the source code to find out this api. -_-"
Putting in javascript in new style gives you this: here
[{"Name":"javascript","Synonyms":"classic-javascript|javascript-execution","Count":223223,"Excerpt":"JavaScript is a dynamic language commonly used for scripting in web browsers. It is NOT the same as Java. Use this tag for questions regarding ECMAScript and its dialects/implementations (excluding ActionScript and JScript). If a framework or library, such as jQuery, is used, include that tag as well. Questions that don't include a framework/library tag, such as jQuery, implies that the question requires a pure JavaScript answer."},{"Name":"javascript-events","Synonyms":"javascript-event","Count":5707,"Excerpt":"Creating and handling JavaScript events inline in HTML or through a script."},{"Name":"facebook-javascript-sdk","Synonyms":"","Count":992,"Excerpt":"Facebook's JavaScript SDK provides a rich set of client-side functionality for accessing Facebook's server-side API calls. These include all of the features of the REST API, Graph API, and Dialogs."},{"Name":"javascript-library","Synonyms":"","Count":675,"Excerpt":"A JavaScript library is a library of pre-written JavaScript which allows for easier development of JavaScript-based applications, especially for AJAX and other web-centric technologies."},{"Name":"javascript-framework","Synonyms":"","Count":563,"Excerpt":"A JavaScript framework is a library of pre-written JavaScript which allows for easier development of JavaScript-based applications, especially for AJAX and other web-centric technologies."},{"Name":"unobtrusive-javascript","Synonyms":"","Count":340,"Excerpt":"Unobtrusive JavaScript is a general approach to the use of JavaScript in web pages."}]
What you can get from there:
All tags start with javascript
Synonyms
Tag counts
Nice tag descriptions
If you're looking for high-level logic, in a nutshell it's just a custom auto-complete that's blazing-fast.
Whenever you type a tag (i.e. a new word or one separated by a space from previous tags), an AJAX request would be made to the server with a JSON object which is then interpreted by the client-side script and presented in the usable layout.
Comparing the autocomplete JSON objects for letter "h" and word "html" should give you enough insight into how this particular implementation works (if prompted, these can be opened with any text editor).
On a somewhat unrelated note: the autocomplete responses have to be fast. Depending on the complexity of the data autocomplete is run against, you may find how IMDb magic search works intriguing.
Update:
Seeing your comment about accessing the content of the tag library, this may in fact be more of a meta question. I struggle to think of a scenario where using an API if any or just the tag library from an external resource would be beneficial to SO - however content here is provided under Creative Commons so you may be able to use it with proper attribution. This does not constitute legal advice :)

Categories