diff options
| -rw-r--r-- | .gitignore | 8 | ||||
| -rw-r--r-- | src/leap/bitmask_js/app/lib/bitmask.js | 259 | ||||
| -rw-r--r-- | src/leap/bitmask_js/app/lib/color.js | 65 | ||||
| -rw-r--r-- | src/leap/bitmask_js/app/lib/colors.js | 289 | ||||
| -rw-r--r-- | src/leap/bitmask_js/app/lib/common.js | 7 | ||||
| -rw-r--r-- | src/leap/bitmask_js/app/lib/validate.js | 82 | 
6 files changed, 702 insertions, 8 deletions
| @@ -13,14 +13,6 @@ env/  build/  develop-eggs/  dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/  *.egg-info/  .installed.cfg  *.egg diff --git a/src/leap/bitmask_js/app/lib/bitmask.js b/src/leap/bitmask_js/app/lib/bitmask.js new file mode 100644 index 0000000..03b6c7b --- /dev/null +++ b/src/leap/bitmask_js/app/lib/bitmask.js @@ -0,0 +1,259 @@ +// bitmask.js +// Copyright (C) 2016 LEAP +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. + +/** + * bitmask object + * + * Contains all the bitmask API mapped by sections + * - user. User management like login, creation, ... + * - mail. Email service control. + * - keys. Keyring operations. + * - events. For registering to events. + * + * Every function returns a Promise that will be triggered once the request is + * finished or will fail if there was any error. Errors are always user readable + * strings. + */ +var bitmask = function(){ +    var event_handlers = {}; + +    function call(command) { +        var url = '/API/' + command.slice(0, 2).join('/'); +        var data = JSON.stringify(command.slice(2)); + +        return new Promise(function(resolve, reject) { +            var req = new XMLHttpRequest(); +            req.open('POST', url); + +            req.onload = function() { +                if (req.status == 200) { +                    parseResponse(req.response, resolve, reject); +                } +                else { +                    reject(Error(req.statusText)); +                } +            }; + +            req.onerror = function() { +                reject(Error("Network Error")); +            }; + +            req.send(data); +        }); +    }; + +    function parseResponse(raw_response, resolve, reject) { +        var response = JSON.parse(raw_response); +        if (response.error === null) { +            resolve(response.result); +        } else { +            reject(response.error); +        } +    }; + +    function event_polling() { +        call(['events', 'poll']).then(function(response) { +            if (response !== null) { +                evnt = response[0]; +                content = response[1]; +                if (evnt in event_handlers) { +                    event_handlers[evnt](evnt, content); +                } +            } +            event_polling(); +        }, function(error) { +            setTimeout(event_polling, 5000); +        }); +    }; +    event_polling(); + +    function private_str(priv) { +        if (priv) { +            return 'private' +        } +        return 'public' +    }; + +    return { +        /** +         * uids are of the form user@provider.net +         */ +        user: { +            /** +             * Check which user is active +             * +             * @return {Promise<string>} The uid of the active user +             */ +            active: function() { +                return call(['user', 'active']); +            }, + +            /** +             * Register a new user +             * +             * @param {string} uid The uid to be created +             * @param {string} password The user password +             */ +            create: function(uid, password) { +                return call(['user', 'create', uid, password]); +            }, + +            /** +             * Login +             * +             * @param {string} uid The uid to log in +             * @param {string} password The user password +             */ +            auth: function(uid, password) { +                return call(['user', 'authenticate', uid, password]); +            }, + +            /** +             * Logout +             * +             * @param {string} uid The uid to log out. +             *                     If no uid is provided the active user will be used +             */ +            logout: function(uid) { +                if (typeof uid !== 'string') { +                    uid = ""; +                } +                return call(['user', 'logout', uid]); +            } +        }, + +        mail: { +            /** +             * Check the status of the email service +             * +             * @return {Promise<string>} User readable status +             */ +            status: function() { +                return call(['mail', 'status']); +            }, + +            /** +             * Get the token of the active user. +             * +             * This token is used as password to authenticate in the IMAP and SMTP services. +             * +             * @return {Promise<string>} The token +             */ +            get_token: function() { +                return call(['mail', 'get-token']); +            } +        }, + +        /** +         * A KeyObject have the following attributes: +         *   - address {string} the email address for wich this key is active +         *   - fingerprint {string} the fingerprint of the key +         *   - length {number} the size of the key bits +         *   - private {bool} if the key is private +         *   - uids {[string]} the uids in the key +         *   - key_data {string} the key content +         *   - validation {string} the validation level which this key was found +         *   - expiry_date {string} date when the key expires +         *   - refreshed_at {string} date of the last refresh of the key +         *   - audited_at {string} date of the last audit (unused for now) +         *   - sign_used {bool} if has being used to checking signatures +         *   - enc_used {bool} if has being used to encrypt +         */ +        keys: { +            /** +             * List all the keys in the keyring +             * +             * @param {boolean} priv Should list private keys? +             *                       If it's not provided the public ones will be listed. +             * +             * @return {Promise<[KeyObject]>} List of keys in the keyring +             */ +            list: function(priv) { +                return call(['keys', 'list', private_str(priv)]); +            }, + +            /** +             * Export key +             * +             * @param {string} address The email address of the key +             * @param {boolean} priv Should get the private key? +             *                       If it's not provided the public one will be fetched. +             * +             * @return {Promise<KeyObject>} The key +             */ +            exprt: function(address, priv) { +                return call(['keys', 'export', address, private_str(priv)]); +            }, + +            /** +             * Insert key +             * +             * @param {string} address The email address of the key +             * @param {string} rawkey The key material +             * @param {string} validation The validation level of the key +             *                            If it's not provided 'Fingerprint' level will be used. +             * +             * @return {Promise<KeyObject>} The key +             */ +            insert: function(address, rawkey, validation) { +                if (typeof validation !== 'string') { +                    validation = 'Fingerprint'; +                } +                return call(['keys', 'insert', address, validation, rawkey]); +            }, + +            /** +             * Delete a key +             * +             * @param {string} address The email address of the key +             * @param {boolean} priv Should get the private key? +             *                       If it's not provided the public one will be deleted. +             * +             * @return {Promise<KeyObject>} The key +             */ +            del: function(address, priv) { +                return call(['keys', 'delete', address, private_str(priv)]); +            } +        }, + +        events: { +            /** +             * Register func for an event +             * +             * @param {string} evnt The event to register +             * @param {function} func The function that will be called on each event. +             *                        It has to be like: function(event, content) {} +             *                        Where content will be a list of strings. +             */ +            register: function(evnt, func) { +                event_handlers[evnt] = func; +                return call(['events', 'register', evnt]) +            }, + +            /** +             * Unregister from an event +             * +             * @param {string} evnt The event to unregister +             */ +            unregister: function(evnt) { +                delete event_handlers[evnt]; +                return call(['events', 'unregister', evnt]) +            } +        } +    }; +}(); + +module.exports = bitmask
\ No newline at end of file diff --git a/src/leap/bitmask_js/app/lib/color.js b/src/leap/bitmask_js/app/lib/color.js new file mode 100644 index 0000000..5b1dfee --- /dev/null +++ b/src/leap/bitmask_js/app/lib/color.js @@ -0,0 +1,65 @@ +// +// Color.hsv().css +// +// RGB values are 0..255 +// HSV values are 0..1 +// + +function compose(value) +  return [ +    Math.round(value * 255), +    Math.round(value * 255), +    Math.round(value * 255) +  } +} + +class Color { + +  constructor(r, g, b, a) { +    this.r = r +    this.g = g +    this.b = b +    this.a = a +  } + +  // +  // alternate hsv factory +  // +  static hsv(h,s,v) { +    let out = null +    h = h % 360; +    s = Math.max(0, Math.min(1, s)) +    v = Math.max(0, Math.min(1, v)) + +    if (s == 0) { +      let grey = Math.ceil(v*255) +      out = [grey, grey, grey] +    } + +    let b = ((1 - s) * v); +    let vb = v - b; +    let hm = h % 60; +    switch((h/60)|0) { +      case 0: +        out = compose(v, vb * h / 60 + b, b); break +      case 1: +        out = compose(vb * (60 - hm) / 60 + b, v, b); break +      case 2: +        out = compose(b, v, vb * hm / 60 + b); break +      case 3: +        out = compose(b, vb * (60 - hm) / 60 + b, v); break +      case 4: +        out = compose(vb * hm / 60 + b, b, v); break +      case 5: +        out = compose(v, b, vb * (60 - hm) / 60 + b); break +    } + +    return new Color(...out) +  } + +  css() { +    return `rgba(${this.r}, ${this.g}, ${this.b}, ${this.a})` +  } +} + +export default Color
\ No newline at end of file diff --git a/src/leap/bitmask_js/app/lib/colors.js b/src/leap/bitmask_js/app/lib/colors.js new file mode 100644 index 0000000..d86ca0a --- /dev/null +++ b/src/leap/bitmask_js/app/lib/colors.js @@ -0,0 +1,289 @@ +// +// a palette from google's material design +// + +export const red50 = '#ffebee'; +export const red100 = '#ffcdd2'; +export const red200 = '#ef9a9a'; +export const red300 = '#e57373'; +export const red400 = '#ef5350'; +export const red500 = '#f44336'; +export const red600 = '#e53935'; +export const red700 = '#d32f2f'; +export const red800 = '#c62828'; +export const red900 = '#b71c1c'; +export const redA100 = '#ff8a80'; +export const redA200 = '#ff5252'; +export const redA400 = '#ff1744'; +export const redA700 = '#d50000'; + +export const pink50 = '#fce4ec'; +export const pink100 = '#f8bbd0'; +export const pink200 = '#f48fb1'; +export const pink300 = '#f06292'; +export const pink400 = '#ec407a'; +export const pink500 = '#e91e63'; +export const pink600 = '#d81b60'; +export const pink700 = '#c2185b'; +export const pink800 = '#ad1457'; +export const pink900 = '#880e4f'; +export const pinkA100 = '#ff80ab'; +export const pinkA200 = '#ff4081'; +export const pinkA400 = '#f50057'; +export const pinkA700 = '#c51162'; + +export const purple50 = '#f3e5f5'; +export const purple100 = '#e1bee7'; +export const purple200 = '#ce93d8'; +export const purple300 = '#ba68c8'; +export const purple400 = '#ab47bc'; +export const purple500 = '#9c27b0'; +export const purple600 = '#8e24aa'; +export const purple700 = '#7b1fa2'; +export const purple800 = '#6a1b9a'; +export const purple900 = '#4a148c'; +export const purpleA100 = '#ea80fc'; +export const purpleA200 = '#e040fb'; +export const purpleA400 = '#d500f9'; +export const purpleA700 = '#aa00ff'; + +export const deepPurple50 = '#ede7f6'; +export const deepPurple100 = '#d1c4e9'; +export const deepPurple200 = '#b39ddb'; +export const deepPurple300 = '#9575cd'; +export const deepPurple400 = '#7e57c2'; +export const deepPurple500 = '#673ab7'; +export const deepPurple600 = '#5e35b1'; +export const deepPurple700 = '#512da8'; +export const deepPurple800 = '#4527a0'; +export const deepPurple900 = '#311b92'; +export const deepPurpleA100 = '#b388ff'; +export const deepPurpleA200 = '#7c4dff'; +export const deepPurpleA400 = '#651fff'; +export const deepPurpleA700 = '#6200ea'; + +export const indigo50 = '#e8eaf6'; +export const indigo100 = '#c5cae9'; +export const indigo200 = '#9fa8da'; +export const indigo300 = '#7986cb'; +export const indigo400 = '#5c6bc0'; +export const indigo500 = '#3f51b5'; +export const indigo600 = '#3949ab'; +export const indigo700 = '#303f9f'; +export const indigo800 = '#283593'; +export const indigo900 = '#1a237e'; +export const indigoA100 = '#8c9eff'; +export const indigoA200 = '#536dfe'; +export const indigoA400 = '#3d5afe'; +export const indigoA700 = '#304ffe'; + +export const blue50 = '#e3f2fd'; +export const blue100 = '#bbdefb'; +export const blue200 = '#90caf9'; +export const blue300 = '#64b5f6'; +export const blue400 = '#42a5f5'; +export const blue500 = '#2196f3'; +export const blue600 = '#1e88e5'; +export const blue700 = '#1976d2'; +export const blue800 = '#1565c0'; +export const blue900 = '#0d47a1'; +export const blueA100 = '#82b1ff'; +export const blueA200 = '#448aff'; +export const blueA400 = '#2979ff'; +export const blueA700 = '#2962ff'; + +export const lightBlue50 = '#e1f5fe'; +export const lightBlue100 = '#b3e5fc'; +export const lightBlue200 = '#81d4fa'; +export const lightBlue300 = '#4fc3f7'; +export const lightBlue400 = '#29b6f6'; +export const lightBlue500 = '#03a9f4'; +export const lightBlue600 = '#039be5'; +export const lightBlue700 = '#0288d1'; +export const lightBlue800 = '#0277bd'; +export const lightBlue900 = '#01579b'; +export const lightBlueA100 = '#80d8ff'; +export const lightBlueA200 = '#40c4ff'; +export const lightBlueA400 = '#00b0ff'; +export const lightBlueA700 = '#0091ea'; + +export const cyan50 = '#e0f7fa'; +export const cyan100 = '#b2ebf2'; +export const cyan200 = '#80deea'; +export const cyan300 = '#4dd0e1'; +export const cyan400 = '#26c6da'; +export const cyan500 = '#00bcd4'; +export const cyan600 = '#00acc1'; +export const cyan700 = '#0097a7'; +export const cyan800 = '#00838f'; +export const cyan900 = '#006064'; +export const cyanA100 = '#84ffff'; +export const cyanA200 = '#18ffff'; +export const cyanA400 = '#00e5ff'; +export const cyanA700 = '#00b8d4'; + +export const teal50 = '#e0f2f1'; +export const teal100 = '#b2dfdb'; +export const teal200 = '#80cbc4'; +export const teal300 = '#4db6ac'; +export const teal400 = '#26a69a'; +export const teal500 = '#009688'; +export const teal600 = '#00897b'; +export const teal700 = '#00796b'; +export const teal800 = '#00695c'; +export const teal900 = '#004d40'; +export const tealA100 = '#a7ffeb'; +export const tealA200 = '#64ffda'; +export const tealA400 = '#1de9b6'; +export const tealA700 = '#00bfa5'; + +export const green50 = '#e8f5e9'; +export const green100 = '#c8e6c9'; +export const green200 = '#a5d6a7'; +export const green300 = '#81c784'; +export const green400 = '#66bb6a'; +export const green500 = '#4caf50'; +export const green600 = '#43a047'; +export const green700 = '#388e3c'; +export const green800 = '#2e7d32'; +export const green900 = '#1b5e20'; +export const greenA100 = '#b9f6ca'; +export const greenA200 = '#69f0ae'; +export const greenA400 = '#00e676'; +export const greenA700 = '#00c853'; + +export const lightGreen50 = '#f1f8e9'; +export const lightGreen100 = '#dcedc8'; +export const lightGreen200 = '#c5e1a5'; +export const lightGreen300 = '#aed581'; +export const lightGreen400 = '#9ccc65'; +export const lightGreen500 = '#8bc34a'; +export const lightGreen600 = '#7cb342'; +export const lightGreen700 = '#689f38'; +export const lightGreen800 = '#558b2f'; +export const lightGreen900 = '#33691e'; +export const lightGreenA100 = '#ccff90'; +export const lightGreenA200 = '#b2ff59'; +export const lightGreenA400 = '#76ff03'; +export const lightGreenA700 = '#64dd17'; + +export const lime50 = '#f9fbe7'; +export const lime100 = '#f0f4c3'; +export const lime200 = '#e6ee9c'; +export const lime300 = '#dce775'; +export const lime400 = '#d4e157'; +export const lime500 = '#cddc39'; +export const lime600 = '#c0ca33'; +export const lime700 = '#afb42b'; +export const lime800 = '#9e9d24'; +export const lime900 = '#827717'; +export const limeA100 = '#f4ff81'; +export const limeA200 = '#eeff41'; +export const limeA400 = '#c6ff00'; +export const limeA700 = '#aeea00'; + +export const yellow50 = '#fffde7'; +export const yellow100 = '#fff9c4'; +export const yellow200 = '#fff59d'; +export const yellow300 = '#fff176'; +export const yellow400 = '#ffee58'; +export const yellow500 = '#ffeb3b'; +export const yellow600 = '#fdd835'; +export const yellow700 = '#fbc02d'; +export const yellow800 = '#f9a825'; +export const yellow900 = '#f57f17'; +export const yellowA100 = '#ffff8d'; +export const yellowA200 = '#ffff00'; +export const yellowA400 = '#ffea00'; +export const yellowA700 = '#ffd600'; + +export const amber50 = '#fff8e1'; +export const amber100 = '#ffecb3'; +export const amber200 = '#ffe082'; +export const amber300 = '#ffd54f'; +export const amber400 = '#ffca28'; +export const amber500 = '#ffc107'; +export const amber600 = '#ffb300'; +export const amber700 = '#ffa000'; +export const amber800 = '#ff8f00'; +export const amber900 = '#ff6f00'; +export const amberA100 = '#ffe57f'; +export const amberA200 = '#ffd740'; +export const amberA400 = '#ffc400'; +export const amberA700 = '#ffab00'; + +export const orange50 = '#fff3e0'; +export const orange100 = '#ffe0b2'; +export const orange200 = '#ffcc80'; +export const orange300 = '#ffb74d'; +export const orange400 = '#ffa726'; +export const orange500 = '#ff9800'; +export const orange600 = '#fb8c00'; +export const orange700 = '#f57c00'; +export const orange800 = '#ef6c00'; +export const orange900 = '#e65100'; +export const orangeA100 = '#ffd180'; +export const orangeA200 = '#ffab40'; +export const orangeA400 = '#ff9100'; +export const orangeA700 = '#ff6d00'; + +export const deepOrange50 = '#fbe9e7'; +export const deepOrange100 = '#ffccbc'; +export const deepOrange200 = '#ffab91'; +export const deepOrange300 = '#ff8a65'; +export const deepOrange400 = '#ff7043'; +export const deepOrange500 = '#ff5722'; +export const deepOrange600 = '#f4511e'; +export const deepOrange700 = '#e64a19'; +export const deepOrange800 = '#d84315'; +export const deepOrange900 = '#bf360c'; +export const deepOrangeA100 = '#ff9e80'; +export const deepOrangeA200 = '#ff6e40'; +export const deepOrangeA400 = '#ff3d00'; +export const deepOrangeA700 = '#dd2c00'; + +export const brown50 = '#efebe9'; +export const brown100 = '#d7ccc8'; +export const brown200 = '#bcaaa4'; +export const brown300 = '#a1887f'; +export const brown400 = '#8d6e63'; +export const brown500 = '#795548'; +export const brown600 = '#6d4c41'; +export const brown700 = '#5d4037'; +export const brown800 = '#4e342e'; +export const brown900 = '#3e2723'; + +export const blueGrey50 = '#eceff1'; +export const blueGrey100 = '#cfd8dc'; +export const blueGrey200 = '#b0bec5'; +export const blueGrey300 = '#90a4ae'; +export const blueGrey400 = '#78909c'; +export const blueGrey500 = '#607d8b'; +export const blueGrey600 = '#546e7a'; +export const blueGrey700 = '#455a64'; +export const blueGrey800 = '#37474f'; +export const blueGrey900 = '#263238'; + +export const grey50 = '#fafafa'; +export const grey100 = '#f5f5f5'; +export const grey200 = '#eeeeee'; +export const grey300 = '#e0e0e0'; +export const grey400 = '#bdbdbd'; +export const grey500 = '#9e9e9e'; +export const grey600 = '#757575'; +export const grey700 = '#616161'; +export const grey800 = '#424242'; +export const grey900 = '#212121'; + +export const black = '#000000'; +export const white = '#ffffff'; + +export const transparent = 'rgba(0, 0, 0, 0)'; +export const fullBlack = 'rgba(0, 0, 0, 1)'; +export const darkBlack = 'rgba(0, 0, 0, 0.87)'; +export const lightBlack = 'rgba(0, 0, 0, 0.54)'; +export const minBlack = 'rgba(0, 0, 0, 0.26)'; +export const faintBlack = 'rgba(0, 0, 0, 0.12)'; +export const fullWhite = 'rgba(255, 255, 255, 1)'; +export const darkWhite = 'rgba(255, 255, 255, 0.87)'; +export const lightWhite = 'rgba(255, 255, 255, 0.54)';
\ No newline at end of file diff --git a/src/leap/bitmask_js/app/lib/common.js b/src/leap/bitmask_js/app/lib/common.js new file mode 100644 index 0000000..14a30c3 --- /dev/null +++ b/src/leap/bitmask_js/app/lib/common.js @@ -0,0 +1,7 @@ +/* + * pollute the global namespace with some useful utils + */ + +import React from 'react' + +window.elem = React.createElement
\ No newline at end of file diff --git a/src/leap/bitmask_js/app/lib/validate.js b/src/leap/bitmask_js/app/lib/validate.js new file mode 100644 index 0000000..4e672e8 --- /dev/null +++ b/src/leap/bitmask_js/app/lib/validate.js @@ -0,0 +1,82 @@ +// https://github.com/dropbox/zxcvbn + +var DOMAIN_RE = /^((?:(?:(?:\w[\.\-\+]?)*)\w)+)((?:(?:(?:\w[\.\-\+]?){0,62})\w)+)\.(\w{2,6})$/ +var USER_RE   = /^[a-z0-9_-]{1,200}$/ +var USER_INT_RE = /^[\.@a-z0-9_-]*$/ + +// +// Validations returns an error message or false if no errors +// + +class Validations { + +  domain(input) { +    if (!input.match(DOMAIN_RE)) { +      return "Not a domain name" +    } else { +      return null +    } +  } + +  usernameInteractive(input) { +    if (!input.match(USER_INT_RE)) { +      return "Username contains an invalid character" +    } +    return false +  } + +  username(input) { +    if (!input.match(USER_INT_RE)) { +      return "Username contains an invalid character" +    } +    if (!input.match('@')) { +      return "Username must be in the form username@domain" +    } +    let parts      = input.split('@') +    let userpart   = parts[0] +    let domainpart = parts[1] +    if (!userpart.match(USER_RE)) { +      return "Username contains an invalid character" +    } else if (!domainpart.match(DOMAIN_RE)) { +      return "Username must include a valid domain name." +    } +    return false +  } + +  passwordStrength(passwd) { +    if (typeof(zxcvbn) == 'function') { +      // zxcvbn performs very slow on long strings, so we cap +      // the calculation at 30 characters +      return zxcvbn(passwd.substring(0,30)) +    } else { +      return null +    } +  } + +  // +  // loads the zxcvbn library. because this library is big, we don't load it +  // every time, just when needed. +  // +  // this is the webpack way to do this: +  // +  //    require.ensure([], function () { +  //      var zxcvbn = require('zxcvbn'); +  //    }); +  // +  // that works, but requires that we also process the original coffeescript +  // source if we want to avoid warning messages. +  // +  loadPasswdLib(onload) { +    var id = "zxcvbn-script" +    if (!document.getElementById(id)) { +      var script = document.createElement('script') +      script.id = id +      script.onload = onload +      script.src = './js/zxcvbn.js' +      document.getElementsByTagName('script')[0].appendChild(script) +    } +  } +} + +var Validate = new Validations() +export default Validate | 
