├── .babelrc
├── .bowerrc
├── .editorconfig
├── .eslintignore
├── .gitattributes
├── .gitignore
├── .yo-rc.json
├── README.md
├── app
├── apple-touch-icon.png
├── davemail.json
├── favicon.ico
├── fonts
│ ├── FontAwesome.otf
│ ├── fontawesome-webfont.eot
│ ├── fontawesome-webfont.svg
│ ├── fontawesome-webfont.ttf
│ ├── fontawesome-webfont.woff
│ └── fontawesome-webfont.woff2
├── images
│ ├── davemail-login.jpg
│ ├── davemail-logo.png
│ ├── davemail.png
│ ├── noise
│ │ ├── noise-loud.png
│ │ ├── noise-soft.png
│ │ └── noise.png
│ ├── paisley
│ │ ├── paisley-lg-100.png
│ │ ├── paisley-lg-loud.png
│ │ ├── paisley-lg-soft.png
│ │ ├── paisley-lg.png
│ │ ├── paisley-loud.png
│ │ ├── paisley-soft.png
│ │ └── paisley.png
│ └── pinstripe
│ │ ├── pinstripe-lg-loud.png
│ │ ├── pinstripe-lg-soft.png
│ │ ├── pinstripe-lg-xloud.png
│ │ ├── pinstripe-lg.png
│ │ ├── pinstripe-loud.png
│ │ ├── pinstripe-md-xloud.png
│ │ ├── pinstripe-sm-loud.png
│ │ ├── pinstripe-sm-soft.png
│ │ ├── pinstripe-sm-xloud.png
│ │ ├── pinstripe-sm.png
│ │ ├── pinstripe-soft.png
│ │ └── pinstripe.png
├── index.html
├── robots.txt
├── scripts
│ └── main.js
└── styles
│ ├── davemail
│ └── style.scss
│ └── main.scss
├── bower.json
├── dist
├── apple-touch-icon.png
├── davemail.json
├── favicon.ico
├── fonts
│ ├── FontAwesome.otf
│ ├── fontawesome-webfont.eot
│ ├── fontawesome-webfont.svg
│ ├── fontawesome-webfont.ttf
│ ├── fontawesome-webfont.woff
│ ├── fontawesome-webfont.woff2
│ ├── glyphicons-halflings-regular.eot
│ ├── glyphicons-halflings-regular.svg
│ ├── glyphicons-halflings-regular.ttf
│ ├── glyphicons-halflings-regular.woff
│ └── glyphicons-halflings-regular.woff2
├── images
│ ├── davemail-login.jpg
│ ├── davemail-logo.png
│ ├── davemail.png
│ ├── noise
│ │ ├── noise-loud.png
│ │ ├── noise-soft.png
│ │ └── noise.png
│ ├── paisley
│ │ ├── paisley-lg-100.png
│ │ ├── paisley-lg-loud.png
│ │ ├── paisley-lg-soft.png
│ │ ├── paisley-lg.png
│ │ ├── paisley-loud.png
│ │ ├── paisley-soft.png
│ │ └── paisley.png
│ └── pinstripe
│ │ ├── pinstripe-lg-loud.png
│ │ ├── pinstripe-lg-soft.png
│ │ ├── pinstripe-lg-xloud.png
│ │ ├── pinstripe-lg.png
│ │ ├── pinstripe-loud.png
│ │ ├── pinstripe-md-xloud.png
│ │ ├── pinstripe-sm-loud.png
│ │ ├── pinstripe-sm-soft.png
│ │ ├── pinstripe-sm-xloud.png
│ │ ├── pinstripe-sm.png
│ │ ├── pinstripe-soft.png
│ │ └── pinstripe.png
├── index.html
├── robots.txt
├── scripts
│ ├── main.js
│ ├── plugins.js
│ ├── vendor.js
│ └── vendor
│ │ └── modernizr.js
└── styles
│ ├── main.css
│ └── vendor.css
├── gulpfile.babel.js
├── package.json
└── test
├── index.html
└── spec
└── test.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "es2015"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "bower_components"
3 | }
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 |
10 | # change these settings to your own preference
11 | indent_style = space
12 | indent_size = 2
13 |
14 | # we recommend you to keep these unchanged
15 | end_of_line = lf
16 | charset = utf-8
17 | trim_trailing_whitespace = true
18 | insert_final_newline = true
19 |
20 | [*.md]
21 | trim_trailing_whitespace = false
22 |
23 | [{package,bower}.json]
24 | indent_style = space
25 | indent_size = 2
26 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | app/scripts/main.js
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | # dist
3 | .tmp
4 | .sass-cache
5 | bower_components
6 | test/bower_components
7 |
--------------------------------------------------------------------------------
/.yo-rc.json:
--------------------------------------------------------------------------------
1 | {
2 | "generator-mocha": {}
3 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Davemail
2 |
3 |
4 |
5 | Decentralised, encrypted, anonymous, offline messaging platform for git. Using the git [distributed version control](https://en.wikipedia.org/wiki/Distributed_version_control#Distributed_vs._centralized) system for encrypted messaging.
6 |
7 | ## Mission Statement
8 |
9 | Empowering you to take back your communication privacy.
10 |
11 | ## Quick Start!
12 |
13 | Clone or download this repository and open `dist/index.html`. Simple!
14 |
15 | ## SMTP email problems
16 |
17 | [SMTP email](https://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol) is one of the oldest technologies on the internet. Emails are sent in plain text accross the internet so anyone listening in can read them. [Edward Snowden](https://en.wikipedia.org/wiki/Edward_Snowden) has revealed that the largest email platforms in the world are in league with government spies with little regard for the fundamental right to privacy, recognized in the UN Declaration of Human Rights.
18 |
19 | ## PGP encryption problems
20 |
21 | [Pretty Good Privacy (PGP)](https://en.wikipedia.org/wiki/Pretty_Good_Privacy) is a solution to some of the problems with SMTP email as the email body is encrypted. However the PGP key pair is created [nondeterministically](https://en.wikipedia.org/wiki/Nondeterministic_algorithm) so the private key must be saved and stored securely in order to decrypt messages. The email metadata (sender, recievers, subject, time) is still prone to interception and mass survailance.
22 |
23 | ## Scrypt and RSA Encrypted Davemail
24 |
25 | Davemail is an alternative to SMTP email. Data is stored in json format with user data separated from the encrypted message data. The json data is open source and decentralised using [git](https://en.wikipedia.org/wiki/Git_(software)) but it is impossible for anyone to deduce which encrypted message was sent to or from which users (unless you hold the key to messages sent to you).
26 |
27 | RSA keys are generated [deterministically](https://en.wikipedia.org/wiki/Deterministic_algorithm) so it is possible to restore long private keys using a strong and memorable passphrase. No need to save and secure a private key on a local machine.
28 |
29 | The [https://github.com/Tarsnap/scrypt](Scrypt) key derivation function makes brute-force attacks costly. Scrypt is applied to all passwords before the RSA keys are generated.
30 |
31 | The Davemail application makes reading and sending encrypted messages easy, hiding the encryption process to improve the user experience. The Davemail application also works offline, so your passphrase can be protected from hackers using keyloggers or screen capture attacks.
32 |
33 |
34 |
35 | ## Decentralisation and anonymity
36 |
37 | This git repository can be cloned and hosted on any computer connected to the internet. SSH access details to these git repositories can be published in the json file, anonymising users. Git repository owners can take responsibility for reducing spam by limiting the frequency of commits.
38 |
39 | ## Example davemail.json file
40 |
41 | ```
42 | {
43 | "davemail": {
44 | "users": {
45 | "davidapple": {
46 | "publicKey": "b8swlmHX6fsc1lSMRjXOqQoYjGf/vtu0wEy4TKudKtpDJ9MzYlg+V1OCpNFZEKq22sYGHjvazxLqy9ugz4nhVAmAMmuYFRukMW1OcNzjdCEu4sno5hUPoSHr0cJb4T2rQl7Tc1dThJmpCbE9NRPA1FZx5XVMhCmiOBTwU+pW0l6BBj+jl2nFeyndknwL/WdN47UEj4Um5yfx/5+I/LS4EIUlme1fkEYe5XjCaM3zFN1UFUw4nDih4MUKrjEE7n2/"
47 | },
48 | "tinyi": {
49 | "publicKey": "nQOZN7PF0Qr5to0xpF6iWGGRU0Yqm4S/0OZVjkx4dldg6+XlxzeJNYQheTh/CTaqiRzVxyUCEekcsVxabGtx9K6xEIVRFP2okGOXYu7zJMKQHf25hW4nWLS/34DJRTibxkq1VzgJ6nlVMwOdUjr0sgqK6vI3X7iEyBKe76I0m610Y2q9hvxNOg+MBQ64dJjdx2wCF9LitxGXy1DaQCa420RE86sHwK9yMrH3mNVRqGmVRX5KkeS2QhHdXwoe4bxV"
50 | }
51 | },
52 | "emails": [
53 | {
54 | "time": "2016-04-11T09:48:41.751Z",
55 | "cipher": "Wn/Oj5fSf+IRPwYYjazM2tpOzRPe81memxXSPqmSGx4eXZkIzVsoPnaMohwTLga8hVNvV6GJan+ZroiDDjD8Kw9MoP+zULmTE1PoI27p/qgSMKBHf7S8mTOvpm5+CzaMjfQhqJ6DcRibnQSQgfKLjn06QjtHt2v9qD0hlKODLrhhVy5m8ShgEHI6/TOyXW3/w/y0NZStPVY8gCJNO1F+zlMsX9QhRYV7XZ8TCExkLdsB3lO6iG7RhxMflb/iMukm?TuyIKKX1YcSQlTQhCOhjxhR2jwjhDD/Z16/xR1lzlg/CjrzbMlsF/p0HoOBZTEcU8Jq+vZ6u/P0I/x20v99P3A=="
56 | },
57 | {
58 | "time": "2016-04-11T09:52:22.194Z",
59 | "cipher": "hltRGEkeFR7zWubXdIspvJtte+/cGHmBnhGvM8U8roTeYA86GuyfVSFDEXhCwipxPtAM0jJmrFpLHBY/51QOf+uHjNxMBxMob+NOme8kiiw3plJeD1Tqv/MwoDWzhA8TQRxvdUPAEjo1BC1wVLFgra30Aw3sblL7UYQnPjcXPDdwFLcRZ+HbMdCqYf3z1fdXvEv7LEoYwSkVivGmdJ520MmVpPzcC+WqXv9I/GuU8oau3CYKJEotZklCIVz0j/u+?NbANPCDdSQvC4HpNXEzZo3HlAAhaxcOlSlkO19x5a3WbOTscl0aYkeXiAdkv5XK2xXPk+uPpwQWOl0ucO4eyDQ=="
60 | }
61 | ],
62 | "servers": [
63 | {
64 | "ssh": "git@github.com:davidapple/davemail.git",
65 | "username": "anonymous",
66 | "password": "example",
67 | "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCB007n/ww+ouN4gSLKssMxXnBOvf9LGt4LojG6rs6hPB09j9R/T17/x4lhJA0F3FR1rP6kYBRsWj2aThGw6HXLm9/5zytK6Ztg3RPKK+4kYjh6541NYsnEAZuXz0jTTyAUfrtU3Z5E003C4oxOj6H0rfIF1kKI9MAQLMdpGW1GYEIgS9EzSdfd8AcCIicTDWbqLAcU4UpkaX8KyGlLwsNuuGztobF8m72ALC/nLF6JLtPofwFBlgc+myivO7TCUSBdLQlgMVOFq1I2uPWQOkOWQAHukEOmfjy2jctxSDBQ220ymjaNsHT4kgtZg2AYYgPqdAv8JggJICUvax2T9va5 gsg-keypair"
68 | }
69 | ]
70 | }
71 | }
72 | ```
73 |
74 | ## Development
75 | Originally created using [Yeoman Webapp Generator](https://github.com/yeoman/generator-webapp).
76 |
77 | ## Getting Started
78 |
79 | - Run `npm install` to install Node Package Manager dependencies
80 | - Run `bower install` to install frontend dependencies
81 | - Run `gulp serve` to preview and watch for changes
82 | - Run `gulp serve:test` to run the tests in the browser
83 | - Run `gulp` to build your webapp for production
84 | - Run `gulp serve:dist` to preview the production build
85 |
86 | ## MIT License
87 |
88 | Copyright (c) 2016 Davemail
89 |
90 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
91 |
92 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
93 |
94 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
95 |
--------------------------------------------------------------------------------
/app/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/apple-touch-icon.png
--------------------------------------------------------------------------------
/app/davemail.json:
--------------------------------------------------------------------------------
1 | {
2 | "davemail": {
3 | "users": {
4 | "tinyi": {
5 | "publicKey": "Waa5H1sVsFmPuDqSZFKMPOgPSmhUQMtcoIaQA87iryXJVH3jhYueW+qIBBOo2x2JNzd05Pm3gJqrFHnFXnJA5UfNIIQlWn6wbxnfced/JRcE2fS0FmrLH+XDB6xms5/ZX+ZzGRKNTOJtk/WNhJSSQsYWa3DbkqZgLMw4m3go9gVeSYN0Isjo2hhQ3fKeW+MrAoaynyRHA6s5OB4I5E/Af71TeqmsLNGl4dlcqYa+ameh6e/PiiKJw6x3SWJJAbYn"
6 | },
7 | "davidapple": {
8 | "publicKey": "TCQy+rIxLzvd0MDap6CT0ZTxZnKQiT9bNyRzr63Ob77Yxe3zUkGNR/qDxhMMNVgZjvFDEA+Z5lnMx+YHCdLni3pN4Ssj4waS+VuixBHRxU90PFLy/pWK08rOf5pEicCStdSQbfe7MQupQN3CUnBCK9gzG7H8RoVBP3pzy4yAv1us7GC+7+urMfxdz1YoZwGOK99okhcXGnb49w2I9B1Aj0qwjVLMTlRypdgikVCEBwLthcbTSSekCDBSyv/296zF"
9 | }
10 | },
11 | "emails": [
12 | {
13 | "time": "2016-05-05T11:14:51.446Z",
14 | "cipher": "Gp4xk6E6NFpm48nHWRHOx1qVRdOtgdZ/lKHBcu8IYA5bFvwf+tUrhNNy+YjyjGRZ8amDubTJzrT+PMFlNm/gbIwho5SbSozMS5qAszscHfXOr3vT2S9NJsbAjm+D8/RdmJI0ZA7omP7ENEBH6VBHMWoDMGfJ/685ic63Bah/wEKBWMk6oL2NtWNVwEiDtwxta72US0oBodzWzKfDSbe+HTuwzcgqL8Grt7YGMsPeZgqO/xyMc9BXcqAGDjY+YLVT?TR2VnwLHpi6j0ofBrFRagI4oEoBczrYnXpaVTfNpRu+NuSnr7vr4ClWpyqWczHi1FzGXzDWFacLVapbaOhYEX142TQCVknCseUCekMWx7bjeRx/8EmN62JVwCRQjq2EE/qKIaxjK7CIByQ+sQPCRmndSzS6D6FUqgRNrNuEgLZAAjWoZbdgEX6vg0P9cHXJ9dznoka3R2sjKiPSPCJRajAqH2eQbEMNGFe5GyfCAxqUx34ryzALYFXq3ZN8wLN0Vx/Ou98mCu0Kqp1XJBWL6qg=="
15 | }
16 | ],
17 | "servers": [
18 | {
19 | "ssh": "git@github.com:davidapple/davemail.git",
20 | "username": "anonymous",
21 | "password": "example",
22 | "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCB007n/ww+ouN4gSLKssMxXnBOvf9LGt4LojG6rs6hPB09j9R/T17/x4lhJA0F3FR1rP6kYBRsWj2aThGw6HXLm9/5zytK6Ztg3RPKK+4kYjh6541NYsnEAZuXz0jTTyAUfrtU3Z5E003C4oxOj6H0rfIF1kKI9MAQLMdpGW1GYEIgS9EzSdfd8AcCIicTDWbqLAcU4UpkaX8KyGlLwsNuuGztobF8m72ALC/nLF6JLtPofwFBlgc+myivO7TCUSBdLQlgMVOFq1I2uPWQOkOWQAHukEOmfjy2jctxSDBQ220ymjaNsHT4kgtZg2AYYgPqdAv8JggJICUvax2T9va5 gsg-keypair"
23 | }
24 | ]
25 | }
26 | }
--------------------------------------------------------------------------------
/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/favicon.ico
--------------------------------------------------------------------------------
/app/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/app/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/app/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/app/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/app/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/app/images/davemail-login.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/davemail-login.jpg
--------------------------------------------------------------------------------
/app/images/davemail-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/davemail-logo.png
--------------------------------------------------------------------------------
/app/images/davemail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/davemail.png
--------------------------------------------------------------------------------
/app/images/noise/noise-loud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/noise/noise-loud.png
--------------------------------------------------------------------------------
/app/images/noise/noise-soft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/noise/noise-soft.png
--------------------------------------------------------------------------------
/app/images/noise/noise.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/noise/noise.png
--------------------------------------------------------------------------------
/app/images/paisley/paisley-lg-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/paisley/paisley-lg-100.png
--------------------------------------------------------------------------------
/app/images/paisley/paisley-lg-loud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/paisley/paisley-lg-loud.png
--------------------------------------------------------------------------------
/app/images/paisley/paisley-lg-soft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/paisley/paisley-lg-soft.png
--------------------------------------------------------------------------------
/app/images/paisley/paisley-lg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/paisley/paisley-lg.png
--------------------------------------------------------------------------------
/app/images/paisley/paisley-loud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/paisley/paisley-loud.png
--------------------------------------------------------------------------------
/app/images/paisley/paisley-soft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/paisley/paisley-soft.png
--------------------------------------------------------------------------------
/app/images/paisley/paisley.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/paisley/paisley.png
--------------------------------------------------------------------------------
/app/images/pinstripe/pinstripe-lg-loud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/pinstripe/pinstripe-lg-loud.png
--------------------------------------------------------------------------------
/app/images/pinstripe/pinstripe-lg-soft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/pinstripe/pinstripe-lg-soft.png
--------------------------------------------------------------------------------
/app/images/pinstripe/pinstripe-lg-xloud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/pinstripe/pinstripe-lg-xloud.png
--------------------------------------------------------------------------------
/app/images/pinstripe/pinstripe-lg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/pinstripe/pinstripe-lg.png
--------------------------------------------------------------------------------
/app/images/pinstripe/pinstripe-loud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/pinstripe/pinstripe-loud.png
--------------------------------------------------------------------------------
/app/images/pinstripe/pinstripe-md-xloud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/pinstripe/pinstripe-md-xloud.png
--------------------------------------------------------------------------------
/app/images/pinstripe/pinstripe-sm-loud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/pinstripe/pinstripe-sm-loud.png
--------------------------------------------------------------------------------
/app/images/pinstripe/pinstripe-sm-soft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/pinstripe/pinstripe-sm-soft.png
--------------------------------------------------------------------------------
/app/images/pinstripe/pinstripe-sm-xloud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/pinstripe/pinstripe-sm-xloud.png
--------------------------------------------------------------------------------
/app/images/pinstripe/pinstripe-sm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/pinstripe/pinstripe-sm.png
--------------------------------------------------------------------------------
/app/images/pinstripe/pinstripe-soft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/pinstripe/pinstripe-soft.png
--------------------------------------------------------------------------------
/app/images/pinstripe/pinstripe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/app/images/pinstripe/pinstripe.png
--------------------------------------------------------------------------------
/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Davemail
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
31 |
32 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
Davemail
63 |
Decentralised, deterministic RSA encrypted, anonymous, offline email for git.
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
Upload file
76 |
You need to upload your davemail.json file.
77 |
78 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
Sign In
98 |
99 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
Under the hood
124 |
The sign in button generates a RSA key pair on your local machine (see browser console).
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
Create a strong password
137 |
If two users share the same password, they will be able to read each others emails! Please choose a very long and unique password.
138 |
139 |
140 |
141 |
142 |
143 |
Sign Up
144 |
145 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
Under the hood
186 |
The sign up button generates a RSA key pair on your local machine (see browser console) and adds the user's username and public RSA key to davemail.json
. This page returns an error if the username is already in the json file. The page uses zxcvbn , preventing users from creating weak passwords.
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
Replace file
198 |
You need to overwrite your davemail.json file.
199 |
and select Save as…
200 |
Then replace the existing davemail.json file with this new one. This new file contains your new data.
201 |
202 |
203 |
204 |
205 |
206 |
Done
207 |
Checking file
208 |
209 |
210 |
211 |
212 |
File not replaced
213 |
You haven't replaced the file davemail.json . Please do this first and then click the Done button.
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
Messages for Anonymous
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
Compose a message
238 |
239 |
240 |
241 |
To
242 |
243 |
244 |
248 |
249 |
250 |
251 | Public key
252 |
253 |
254 |
255 |
256 |
257 |
Message
258 |
259 |
260 |
261 |
262 | Show Public Key
263 |
264 |
265 |
266 |
Send
267 |
Sending
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
--------------------------------------------------------------------------------
/app/robots.txt:
--------------------------------------------------------------------------------
1 | # robotstxt.org/
2 |
3 | User-agent: *
4 | Disallow:
5 |
--------------------------------------------------------------------------------
/app/scripts/main.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | (function(){
4 | window.davemail = new Object();
5 | davemail.info = 'Davemail 2.0.0 by David Apple https://github.com/davidapple/davemail Donate Bitcoin to 13D3A8PP91MLF5VTBQMH5HG76F42RNRF28';
6 |
7 | var scrypt = scrypt_module_factory(); // https://github.com/tonyg/js-scrypt
8 |
9 | // - Functions
10 | function loadDavemail(){
11 | return $.getJSON('davemail.json', function() {
12 | console.log('davemail.json loaded confirmation one');
13 | })
14 | .done(function() {
15 | console.log('davemail.json loaded confirmation two');
16 | })
17 | .fail(function( jqxhr, textStatus, error ) {
18 | var err = textStatus + ", " + error;
19 | console.log('davemail.json failed to load: ' + err );
20 | importPage();
21 | });
22 | }
23 |
24 | function loadDavemailAgain(davemail){
25 | var newDavemail = $.getJSON('davemail.json', function() {
26 | console.log('davemail.json loaded confirmation one');
27 | })
28 | .done(function(response) {
29 | console.log('davemail.json loaded confirmation two');
30 | if(_.isEqual(davemail.jsonData.responseJSON, response)){
31 | $('#signUpReplaceDownload').remove();
32 | $('#signUpButton').show();
33 | $('#signingUpLoader').hide();
34 | $('#fileReplacedButton').show();
35 | $('#fileReplacedLoader').hide();
36 | $('#usernameHeading').text(davemail.username);
37 | messagesPage();
38 | davemail.messages = mapMessages(davemail);
39 | buildMessagesTable(davemail);
40 | }else{
41 | $('#fileNotReplacedWarning').show();
42 | $('#fileReplacedLoader').hide();
43 | $('#fileReplacedButton').show();
44 | }
45 | })
46 | .fail(function( jqxhr, textStatus, error ) {
47 | var err = textStatus + ", " + error;
48 | console.log('davemail.json failed to load: ' + err );
49 |
50 | // Let the user progress in the hope that they have successfully replaced their json file
51 | $('#signUpReplaceDownload').remove();
52 | $('#signUpButton').show();
53 | $('#signingUpLoader').hide();
54 | $('#fileReplacedButton').show();
55 | $('#fileReplacedLoader').hide();
56 | $('#usernameHeading').text(davemail.username);
57 | messagesPage();
58 | davemail.messages = mapMessages(davemail);
59 | buildMessagesTable(davemail);
60 |
61 | });
62 | }
63 |
64 | function composeInit(davemail){
65 | $('#composeToList li').remove();
66 | var usersArray = _.map(davemail.jsonData.responseJSON.davemail.users, function(num, key){
67 | $('').text(key).click(function(event){
68 | $('#composeTo').val(key);
69 | $('#composeTo').removeClass('invalid');
70 | $('#composePublicKey').val(num.publicKey);
71 | $('#composeToListWrapper').hide();
72 | $('#composeSendButton').show();
73 | }).appendTo('#composeToList');
74 | return key;
75 | });
76 | var filter = $('#composeTo'), clearfilter = $('input#clearfilter');
77 | $('#composeToList').listfilter({
78 | 'filter': filter,
79 | 'clearlink': clearfilter,
80 | 'alternate': true,
81 | 'alternateclass': 'other'
82 | });
83 | $('#composeTo').keyup(function(){
84 | if($('#composeTo').val().length > 0){
85 | $('#composeToListWrapper').show();
86 | if($('#composeToList li:visible').length == 0){
87 | $('#composeToListWrapper').hide();
88 | }
89 | if(_.indexOf(usersArray, $('#composeTo').val()) == -1){
90 | $('#composePublicKey').val('');
91 | $('#composeSendButton').hide();
92 | }else{
93 | $('#composePublicKey').val(davemail.jsonData.responseJSON.davemail.users[$('#composeTo').val()].publicKey);
94 | $('#composeSendButton').show();
95 | }
96 | }else{
97 | $('#composeToListWrapper').hide();
98 | }
99 | }).focusout(function(){
100 | setTimeout(function (){
101 | if(_.indexOf(usersArray, $('#composeTo').val()) == -1){
102 | $('#composeTo').addClass('invalid');
103 | }else{
104 | $('#composeTo').removeClass('invalid');
105 | $('#composeToListWrapper').hide();
106 | }
107 | }, 10);
108 | });
109 | $('#composePublicKeyButton').click(function(){
110 | if ($(this).prop('checked')){
111 | $('#composeShowPublicKey').show();
112 | }else{
113 | $('#composeShowPublicKey').hide();
114 | }
115 | });
116 | }
117 |
118 | function importPage(event){
119 | if(_.isObject(event)){
120 | event.preventDefault();
121 | }
122 | $('#importDavemail').show();
123 | $('nav').hide();
124 | $('#signIn').hide();
125 | $('#signUp').hide();
126 | $('#messages').hide();
127 | $('#signUpReplace').hide();
128 | $('#navSignInButton').parent().removeClass('active');
129 | $('#navSignUpButton').parent().removeClass('active');
130 | $('#navMessagesButton').parent().removeClass('active');
131 | }
132 | function signInPage(event){
133 | if(_.isObject(event)){
134 | event.preventDefault();
135 | }
136 | $('#signIn').show();
137 | $('#signUp').hide();
138 | $('#messages').hide();
139 | $('#signUpReplace').hide();
140 | $('#navSignInButton').parent().addClass('active');
141 | $('#navSignUpButton').parent().removeClass('active');
142 | $('#navMessagesButton').parent().removeClass('active');
143 | }
144 | function signUpPage(event){
145 | if(_.isObject(event)){
146 | event.preventDefault();
147 | }
148 | $('#signUp').show();
149 | $('#signIn').hide();
150 | $('#messages').hide();
151 | $('#navSignUpButton').parent().addClass('active');
152 | $('#navSignInButton').parent().removeClass('active');
153 | $('#navMessagesButton').parent().removeClass('active');
154 | }
155 | function messagesPage(event){
156 | if(_.isObject(event)){
157 | event.preventDefault();
158 | }
159 | $('#messages').show();
160 | $('#compose').hide();
161 | $('#signIn').hide();
162 | $('#signUp').hide();
163 | $('#signUpReplace').hide();
164 | $('#navMessagesButton').show();
165 | $('#navMessagesButton').parent().addClass('active');
166 | $('#navComposeButton').show();
167 | $('#navComposeButton').parent().removeClass('active');
168 | $('#navSignInButton').parent().removeClass('active');
169 | $('#navSignUpButton').parent().removeClass('active');
170 | $('#navSignOutButton').show();
171 | $('#navSignInButton').hide();
172 | $('#navSignUpButton').hide();
173 | $('.jumbotron').hide();
174 | }
175 | function composePage(event){
176 | if(_.isObject(event)){
177 | event.preventDefault();
178 | }
179 | $('#messages').hide();
180 | $('#compose').show();
181 | $('#signIn').hide();
182 | $('#signUp').hide();
183 | $('#signUpReplace').hide();
184 | $('#navMessagesButton').show();
185 | $('#navMessagesButton').parent().removeClass('active');
186 | $('#navComposeButton').show();
187 | $('#navComposeButton').parent().addClass('active');
188 | $('#navSignInButton').parent().removeClass('active');
189 | $('#navSignUpButton').parent().removeClass('active');
190 | $('#navSignOutButton').show();
191 | $('#navSignInButton').hide();
192 | $('#navSignUpButton').hide();
193 | $('.jumbotron').hide();
194 | }
195 | function signOutPage(event){
196 | if(_.isObject(event)){
197 | event.preventDefault();
198 | }
199 | $('#signIn').show();
200 | $('#signInButton').show();
201 | $('#messages').hide();
202 | $('#compose').hide();
203 | $('#signUp').hide();
204 | $('#signUpReplace').hide();
205 | $('#navComposeButton').hide();
206 | $('#navMessagesButton').hide();
207 | $('#navSignInButton').parent().addClass('active');
208 | $('#navComposeButton').parent().removeClass('active');
209 | $('#navMessagesButton').parent().removeClass('active');
210 | $('#navSignUpButton').parent().removeClass('active');
211 | $('#navSignInButton').show();
212 | $('#navSignUpButton').show();
213 | $('#navSignOutButton').hide();
214 | $('#composeTo').val('');
215 | $('#composeTo').removeClass('invalid');
216 | $('#composePublicKey').val('');
217 | $('#composeShowPublicKey').hide();
218 | $('#composePublicKeyButton').attr('checked', false)
219 | $('.jumbotron').show();
220 | }
221 | function signOut(davemail){
222 | davemail.messagesTable.destroy();
223 | davemail.messagesTable = $('#messagesTable').DataTable({
224 | data: [],
225 | ordering: false,
226 | columns: [
227 | {title: "Message"},
228 | {title: "Time"}
229 | ]
230 | });
231 | davemail.username = undefined;
232 | davemail.password = undefined;
233 | davemail.passwordStrength = undefined;
234 | davemail.publicKey = undefined;
235 | davemail.privateKey = undefined;
236 | davemail.messages = undefined;
237 | return davemail;
238 | }
239 | function scryptMe(string){
240 | // Scrypt - https://github.com/tonyg/js-scrypt
241 | var newString = string;
242 | var utf8String = scrypt.encode_utf8(newString);
243 | var utf8Salt = scrypt.encode_utf8('davemail');
244 | var utf8StringScrypt = scrypt.crypto_scrypt(utf8String, utf8Salt, Math.pow(2, 14), 8, 1, 64);
245 | newString = scrypt.to_hex(utf8StringScrypt);
246 | console.log(newString);
247 | return newString;
248 | }
249 | function generateKeyPair(davemail){
250 | davemail.privateKey = cryptico.generateRSAKey(scryptMe(davemail.password), 1536);
251 | davemail.publicKey = cryptico.publicKeyString(davemail.privateKey);
252 | console.log(davemail.privateKey);
253 | console.log(davemail.publicKey);
254 | return davemail;
255 | }
256 | function encryptMessage(string, time, key){
257 | var nonce = scryptMe(time);
258 | var message = cryptico.encrypt(string.concat(nonce), key);
259 | return message;
260 | }
261 |
262 | function mapMessages(davemail){
263 | davemail.decryptedMessages = new Array();
264 | return _.map(davemail.jsonData.responseJSON.davemail.emails, function(num, key){
265 | var message = cryptico.decrypt(num.cipher, davemail.privateKey);
266 | if (message.status == 'success'){
267 | var timeReadable = moment(num.time).format("MMM Do YY");
268 | var messageWithoutNonce = message.plaintext.substring(0, (message.plaintext.length) - 128);
269 | davemail.decryptedMessages.push([ messageWithoutNonce, timeReadable ]);
270 | return [ messageWithoutNonce, timeReadable ];
271 | }
272 | });
273 | }
274 |
275 | function buildMessagesTable(davemail){
276 | if (!_.isUndefined(davemail.decryptedMessages[0])){
277 | davemail.messagesTable.destroy();
278 | davemail.messagesTable = $('#messagesTable').DataTable({
279 | data: davemail.decryptedMessages,
280 | ordering: false,
281 | columns: [
282 | {title: "Message"},
283 | {title: "Time"}
284 | ]
285 | });
286 | }
287 | }
288 |
289 | // - Application
290 |
291 | // Load davemail.json
292 | davemail.jsonData = loadDavemail();
293 |
294 | // Let users upload davemail.json if it fails to load
295 | $(document).on('change', '#importDavemailFile', function(event){
296 | var reader = new FileReader();
297 | $('#importDavemailButton').hide();
298 | $('#importingLoader').show();
299 | reader.onload = function(event){
300 | console.log('davemail.json loaded confirmation one');
301 | var jsonObj = JSON.parse(event.target.result);
302 | davemail.jsonData = new Object();
303 | davemail.jsonData.responseJSON = jsonObj;
304 | $('nav').show();
305 | $('#signIn').show();
306 | $('#importDavemail').hide();
307 | }
308 | reader.readAsText(event.target.files[0]);
309 | });
310 |
311 | $('#navSignInButton').click(function(event){
312 | signInPage(event);
313 | });
314 | $('#navSignUpButton').click(function(event){
315 | signUpPage(event);
316 | });
317 | $('#navMessagesButton').click(function(event){
318 | messagesPage(event);
319 | });
320 | $('#navComposeButton').click(function(event){
321 | composePage(event);
322 | });
323 | $('#navSignOutButton').click(function(event){
324 | signOutPage(event);
325 | davemail = signOut(davemail);
326 | });
327 | $('#signUpButtonOnSignIn').click(function(event){
328 | signUpPage(event);
329 | });
330 |
331 | davemail.messagesTable = $('#messagesTable').DataTable({
332 | data: [],
333 | ordering: false,
334 | columns: [
335 | {title: "Message"},
336 | {title: "Time"}
337 | ]
338 | });
339 |
340 | $('#signInButton').click(function(){
341 |
342 | $('#signInButton').hide();
343 | $('#signingInLoader').show();
344 |
345 | davemail.password = $('#signInPassword').val();
346 | davemail.passwordStrength = zxcvbn(davemail.password);
347 |
348 | if(davemail.passwordStrength.score < 4){
349 | setTimeout(function (){
350 | $('#passwordWarningSignIn').show();
351 | $('#signInButton').show();
352 | $('#signingInLoader').hide();
353 | }, 100);
354 | }else{
355 | setTimeout(function (){
356 | davemail = generateKeyPair(davemail);
357 |
358 | _.map(davemail.jsonData.responseJSON.davemail.users, function(num, key){
359 | if(davemail.publicKey == num.publicKey){
360 | $('#usernameHeading').text(key);
361 | davemail.username = key;
362 | }
363 | });
364 |
365 | $('#signingInLoader').hide();
366 | $('#signIn').hide();
367 | $('#signInPassword').val('');
368 |
369 | messagesPage();
370 | davemail.messages = mapMessages(davemail);
371 | buildMessagesTable(davemail);
372 | composeInit(davemail);
373 |
374 | }, 10);
375 | }
376 | });
377 |
378 | $('#signUpButton').click(function(){
379 |
380 | $('#signUpUsername').val($('#signUpUsername').val().toLowerCase());
381 | davemail.username = $('#signUpUsername').val();
382 | davemail.password = $('#signUpPassword').val();
383 | davemail.passwordStrength = zxcvbn(davemail.password);
384 |
385 | $('#usernameTakenWarning').hide();
386 | $('#passwordWarning').hide();
387 |
388 | if(davemail.username.length > 0){
389 | $('#usernameEmptyWarning').hide();
390 |
391 | // TODO: Simplify this logic
392 | var usernameTaken = _.map(davemail.jsonData.responseJSON.davemail.users, function(num, key){
393 | if(davemail.username == key.toLowerCase()){
394 | return true;
395 | }else{
396 | return false;
397 | }
398 | });
399 |
400 | if(_.contains(usernameTaken, true)){
401 | $('#usernameTakenWarning').show();
402 | $('#passwordWarning').hide();
403 | usernameTaken = true;
404 | }else{
405 | usernameTaken = false;
406 | }
407 |
408 | var usernameLegal = /^[a-z0-9]*$/.test(davemail.username);
409 |
410 | if(!usernameLegal){
411 | $('#usernameIllegalWarning').show();
412 | }else{
413 | $('#usernameIllegalWarning').hide();
414 | }
415 |
416 | if(usernameLegal && (!usernameTaken) && davemail.passwordStrength.score > 3){
417 | $('#passwordWarning').hide();
418 | $('#signUpButton').hide();
419 | $('#signingUpLoader').show();
420 |
421 | setTimeout(function (){
422 | davemail = generateKeyPair(davemail);
423 |
424 | // Regenerate users json
425 | var users = davemail.jsonData.responseJSON.davemail.users;
426 | var emails = davemail.jsonData.responseJSON.davemail.emails;
427 | var servers = davemail.jsonData.responseJSON.davemail.servers;
428 | users[davemail.username] = {'publicKey': davemail.publicKey}; // Add user to users
429 |
430 | davemail.jsonData.responseJSON = {'davemail': {'users': users, 'emails': emails, 'servers': servers}}; // Replace local json
431 | $('#signUpJson').text(JSON.stringify(davemail.jsonData.responseJSON, null, 4));
432 |
433 | var data = "text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(davemail.jsonData.responseJSON, null, 4));
434 | $('#signUpUsername').val('');
435 | $('#signUpPassword').val('');
436 | $('#signUp').hide();
437 | $('#signUpReplace').show();
438 | $('Right click here ').appendTo('#signUpDownload');
439 |
440 | composeInit(davemail);
441 |
442 | }, 100);
443 |
444 | }else{
445 | if(davemail.passwordStrength.score < 4){
446 | $('#passwordWarning').show();
447 | }
448 | $('#passwordWarningText').text(davemail.passwordStrength.feedback.warning);
449 | var passwordSuggestions = $('#passwordSuggestionsText');
450 | passwordSuggestions.children().remove();
451 | $.each(davemail.passwordStrength.feedback.suggestions, function(i){
452 | var p = $('
')
453 | .appendTo(passwordSuggestions)
454 | .text(davemail.passwordStrength.feedback.suggestions[i])
455 | .appendTo(p);
456 | });
457 | }
458 | }else{
459 | $('#usernameEmptyWarning').show();
460 | }
461 | });
462 |
463 | $('#composeSendButton').click(function(){
464 | if(davemail.jsonData.responseJSON.davemail.users[$('#composeTo').val()].publicKey == $('#composePublicKey').val()){
465 | $(this).hide();
466 | $('#sendingLoader').show();
467 | var date = new Date();
468 | var message = encryptMessage($('#composeMessage').val(), date.toISOString(), $('#composePublicKey').val());
469 | console.log(message);
470 | if(message.status == 'success'){
471 | setTimeout(function (){
472 | $('#composeTo').val('');
473 | $('#composePublicKey').val('');
474 | $('#composeMessage').val('');
475 | $('#sendingLoader').hide();
476 | $('#compose').hide();
477 | $('#signUpReplace').show();
478 |
479 | // Regenerate emails json
480 | var users = davemail.jsonData.responseJSON.davemail.users;
481 | var emails = davemail.jsonData.responseJSON.davemail.emails;
482 | var servers = davemail.jsonData.responseJSON.davemail.servers;
483 | emails.push({'time': date.toISOString(), 'cipher': message.cipher}); // Add user to users
484 |
485 | davemail.jsonData.responseJSON = {'davemail': {'users': users, 'emails': emails, 'servers': servers}}; // Replace local json
486 | $('#signUpJson').text(JSON.stringify(davemail.jsonData.responseJSON, null, 4));
487 |
488 | var data = "text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(davemail.jsonData.responseJSON, null, 4));
489 | $('Right click here ').appendTo('#signUpDownload');
490 |
491 | }, 100);
492 | }
493 | }else{
494 | console.log('fail');
495 | }
496 | });
497 |
498 | $('#fileReplacedButton').click(function(){
499 | $('#fileReplacedButton').hide();
500 | $('#fileReplacedLoader').show();
501 | setTimeout(function (){
502 | loadDavemailAgain(davemail);
503 | }, 500);
504 | });
505 |
506 | })();
507 |
--------------------------------------------------------------------------------
/app/styles/davemail/style.scss:
--------------------------------------------------------------------------------
1 | .jumbotron {
2 | color:#ffffff;
3 | background-color: #2c3b63;
4 | img {
5 | max-height: 160px;
6 | }
7 | p {
8 | font-size: 14px;
9 | }
10 | }
11 | .btn-primary {
12 | border-color: #2c3b63;
13 | background-color: #2c3b63;
14 | }
15 | #messagesTable_wrapper {
16 | margin-top: 40px;
17 | margin-bottom: 40px;
18 | thead {
19 | display: none;
20 | }
21 | td:first-child {
22 | width: 85%;
23 | }
24 | }
25 |
26 | .davemail-messages-table {
27 | width: 100% !important;
28 | }
29 | .davemail-sign-up-username {
30 | text-transform: lowercase;
31 | }
32 | .inline-block {
33 | display: inline-block !important;
34 | }
35 | .compose-users-list-wrapper {
36 | top: -1px;
37 | position: relative;
38 | }
39 | .compose-users-list {
40 | position: absolute;
41 | width: 100%;
42 | border: 1px solid #cccccc;
43 | background-color: #ffffff;
44 | box-shadow: 0 2px 4px rgba(0,0,0,0.2);
45 | -webkit-box-shadow: 0 2px 4px rgba(0,0,0,0.2);
46 | li {
47 | padding: 1px 12px;
48 | list-style-type: none;
49 | &:hover {
50 | background-color: #eeeeee;
51 | }
52 | }
53 | }
54 | .show-public-key {
55 | color: #999999;
56 | }
57 | .invalid {
58 | border-color: #fd6e8a;
59 | }
--------------------------------------------------------------------------------
/app/styles/main.scss:
--------------------------------------------------------------------------------
1 | $icon-font-path: '../fonts/';
2 |
3 | // bower:scss
4 | @import "bower_components/bootstrap-sass/assets/stylesheets/_bootstrap.scss";
5 | @import "bower_components/font-awesome/scss/font-awesome.scss";
6 | @import "bower_components/tailor/sass/tailor.scss";
7 | @import "app/styles/davemail/style.scss";
8 | @import "bower_components/nudge/sass/nudge.scss";
9 | // endbower
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "davemail",
3 | "version": "2.0.0",
4 | "private": false,
5 | "dependencies": {
6 | "bootstrap-sass": "~3.3.5",
7 | "modernizr": "~2.8.1",
8 | "nudge": "^1.2.3",
9 | "font-awesome": "^4.5.0",
10 | "datatables": "^1.10.11",
11 | "underscore": "^1.8.3",
12 | "js-scrypt": "git://github.com/tonyg/js-scrypt.git#1427dcb6f58385fb83aafeb6d5ec05b3d1d72ec2",
13 | "cryptico": "git://github.com/wwwtyro/cryptico.git#9291ece634d37415e66396d749d38e612d66f935",
14 | "zxcvbn": "^4.3.0",
15 | "jquery.listfilter": "^1.0.10",
16 | "tailor": "git://github.com/davidapple/tailor",
17 | "moment": "^2.13.0"
18 | },
19 | "overrides": {
20 | "bootstrap-sass": {
21 | "main": [
22 | "assets/stylesheets/_bootstrap.scss",
23 | "assets/fonts/bootstrap/*",
24 | "assets/javascripts/bootstrap.js"
25 | ]
26 | }
27 | },
28 | "devDependencies": {
29 | "chai": "^3.5.0",
30 | "mocha": "^2.4.5"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/dist/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/apple-touch-icon.png
--------------------------------------------------------------------------------
/dist/davemail.json:
--------------------------------------------------------------------------------
1 | {
2 | "davemail": {
3 | "users": {
4 | "tinyi": {
5 | "publicKey": "Waa5H1sVsFmPuDqSZFKMPOgPSmhUQMtcoIaQA87iryXJVH3jhYueW+qIBBOo2x2JNzd05Pm3gJqrFHnFXnJA5UfNIIQlWn6wbxnfced/JRcE2fS0FmrLH+XDB6xms5/ZX+ZzGRKNTOJtk/WNhJSSQsYWa3DbkqZgLMw4m3go9gVeSYN0Isjo2hhQ3fKeW+MrAoaynyRHA6s5OB4I5E/Af71TeqmsLNGl4dlcqYa+ameh6e/PiiKJw6x3SWJJAbYn"
6 | },
7 | "davidapple": {
8 | "publicKey": "TCQy+rIxLzvd0MDap6CT0ZTxZnKQiT9bNyRzr63Ob77Yxe3zUkGNR/qDxhMMNVgZjvFDEA+Z5lnMx+YHCdLni3pN4Ssj4waS+VuixBHRxU90PFLy/pWK08rOf5pEicCStdSQbfe7MQupQN3CUnBCK9gzG7H8RoVBP3pzy4yAv1us7GC+7+urMfxdz1YoZwGOK99okhcXGnb49w2I9B1Aj0qwjVLMTlRypdgikVCEBwLthcbTSSekCDBSyv/296zF"
9 | }
10 | },
11 | "emails": [
12 | {
13 | "time": "2016-05-05T11:14:51.446Z",
14 | "cipher": "Gp4xk6E6NFpm48nHWRHOx1qVRdOtgdZ/lKHBcu8IYA5bFvwf+tUrhNNy+YjyjGRZ8amDubTJzrT+PMFlNm/gbIwho5SbSozMS5qAszscHfXOr3vT2S9NJsbAjm+D8/RdmJI0ZA7omP7ENEBH6VBHMWoDMGfJ/685ic63Bah/wEKBWMk6oL2NtWNVwEiDtwxta72US0oBodzWzKfDSbe+HTuwzcgqL8Grt7YGMsPeZgqO/xyMc9BXcqAGDjY+YLVT?TR2VnwLHpi6j0ofBrFRagI4oEoBczrYnXpaVTfNpRu+NuSnr7vr4ClWpyqWczHi1FzGXzDWFacLVapbaOhYEX142TQCVknCseUCekMWx7bjeRx/8EmN62JVwCRQjq2EE/qKIaxjK7CIByQ+sQPCRmndSzS6D6FUqgRNrNuEgLZAAjWoZbdgEX6vg0P9cHXJ9dznoka3R2sjKiPSPCJRajAqH2eQbEMNGFe5GyfCAxqUx34ryzALYFXq3ZN8wLN0Vx/Ou98mCu0Kqp1XJBWL6qg=="
15 | }
16 | ],
17 | "servers": [
18 | {
19 | "ssh": "git@github.com:davidapple/davemail.git",
20 | "username": "anonymous",
21 | "password": "example",
22 | "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCB007n/ww+ouN4gSLKssMxXnBOvf9LGt4LojG6rs6hPB09j9R/T17/x4lhJA0F3FR1rP6kYBRsWj2aThGw6HXLm9/5zytK6Ztg3RPKK+4kYjh6541NYsnEAZuXz0jTTyAUfrtU3Z5E003C4oxOj6H0rfIF1kKI9MAQLMdpGW1GYEIgS9EzSdfd8AcCIicTDWbqLAcU4UpkaX8KyGlLwsNuuGztobF8m72ALC/nLF6JLtPofwFBlgc+myivO7TCUSBdLQlgMVOFq1I2uPWQOkOWQAHukEOmfjy2jctxSDBQ220ymjaNsHT4kgtZg2AYYgPqdAv8JggJICUvax2T9va5 gsg-keypair"
23 | }
24 | ]
25 | }
26 | }
--------------------------------------------------------------------------------
/dist/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/favicon.ico
--------------------------------------------------------------------------------
/dist/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/dist/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/dist/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/dist/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/dist/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/dist/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/dist/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/dist/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/dist/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/dist/images/davemail-login.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/davemail-login.jpg
--------------------------------------------------------------------------------
/dist/images/davemail-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/davemail-logo.png
--------------------------------------------------------------------------------
/dist/images/davemail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/davemail.png
--------------------------------------------------------------------------------
/dist/images/noise/noise-loud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/noise/noise-loud.png
--------------------------------------------------------------------------------
/dist/images/noise/noise-soft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/noise/noise-soft.png
--------------------------------------------------------------------------------
/dist/images/noise/noise.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/noise/noise.png
--------------------------------------------------------------------------------
/dist/images/paisley/paisley-lg-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/paisley/paisley-lg-100.png
--------------------------------------------------------------------------------
/dist/images/paisley/paisley-lg-loud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/paisley/paisley-lg-loud.png
--------------------------------------------------------------------------------
/dist/images/paisley/paisley-lg-soft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/paisley/paisley-lg-soft.png
--------------------------------------------------------------------------------
/dist/images/paisley/paisley-lg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/paisley/paisley-lg.png
--------------------------------------------------------------------------------
/dist/images/paisley/paisley-loud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/paisley/paisley-loud.png
--------------------------------------------------------------------------------
/dist/images/paisley/paisley-soft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/paisley/paisley-soft.png
--------------------------------------------------------------------------------
/dist/images/paisley/paisley.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/paisley/paisley.png
--------------------------------------------------------------------------------
/dist/images/pinstripe/pinstripe-lg-loud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/pinstripe/pinstripe-lg-loud.png
--------------------------------------------------------------------------------
/dist/images/pinstripe/pinstripe-lg-soft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/pinstripe/pinstripe-lg-soft.png
--------------------------------------------------------------------------------
/dist/images/pinstripe/pinstripe-lg-xloud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/pinstripe/pinstripe-lg-xloud.png
--------------------------------------------------------------------------------
/dist/images/pinstripe/pinstripe-lg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/pinstripe/pinstripe-lg.png
--------------------------------------------------------------------------------
/dist/images/pinstripe/pinstripe-loud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/pinstripe/pinstripe-loud.png
--------------------------------------------------------------------------------
/dist/images/pinstripe/pinstripe-md-xloud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/pinstripe/pinstripe-md-xloud.png
--------------------------------------------------------------------------------
/dist/images/pinstripe/pinstripe-sm-loud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/pinstripe/pinstripe-sm-loud.png
--------------------------------------------------------------------------------
/dist/images/pinstripe/pinstripe-sm-soft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/pinstripe/pinstripe-sm-soft.png
--------------------------------------------------------------------------------
/dist/images/pinstripe/pinstripe-sm-xloud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/pinstripe/pinstripe-sm-xloud.png
--------------------------------------------------------------------------------
/dist/images/pinstripe/pinstripe-sm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/pinstripe/pinstripe-sm.png
--------------------------------------------------------------------------------
/dist/images/pinstripe/pinstripe-soft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/pinstripe/pinstripe-soft.png
--------------------------------------------------------------------------------
/dist/images/pinstripe/pinstripe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/davidapple/davemail/0e922739ae73e7630c8166f85565f77215fb06a0/dist/images/pinstripe/pinstripe.png
--------------------------------------------------------------------------------
/dist/index.html:
--------------------------------------------------------------------------------
1 | Davemail Davemail Decentralised, deterministic RSA encrypted, anonymous, offline email for git.
Upload file You need to upload your davemail.json file.
Under the hood The sign in button generates a RSA key pair on your local machine (see browser console).
Create a strong password If two users share the same password, they will be able to read each others emails! Please choose a very long and unique password.
Under the hood The sign up button generates a RSA key pair on your local machine (see browser console) and adds the user's username and public RSA key to davemail.json
. This page returns an error if the username is already in the json file. The page uses zxcvbn , preventing users from creating weak passwords.
Replace file You need to overwrite your davemail.json file.
and select Save as…
Then replace the existing davemail.json file with this new one. This new file contains your new data.
File not replaced You haven't replaced the file davemail.json . Please do this first and then click the Done button.
--------------------------------------------------------------------------------
/dist/robots.txt:
--------------------------------------------------------------------------------
1 | # robotstxt.org/
2 |
3 | User-agent: *
4 | Disallow:
5 |
--------------------------------------------------------------------------------
/dist/scripts/main.js:
--------------------------------------------------------------------------------
1 | "use strict";!function(){function e(){return $.getJSON("davemail.json",function(){console.log("davemail.json loaded confirmation one")}).done(function(){console.log("davemail.json loaded confirmation two")}).fail(function(e,a,n){var o=a+", "+n;console.log("davemail.json failed to load: "+o),s()})}function a(e){$.getJSON("davemail.json",function(){console.log("davemail.json loaded confirmation one")}).done(function(a){console.log("davemail.json loaded confirmation two"),_.isEqual(e.jsonData.responseJSON,a)?($("#signUpReplaceDownload").remove(),$("#signUpButton").show(),$("#signingUpLoader").hide(),$("#fileReplacedButton").show(),$("#fileReplacedLoader").hide(),$("#usernameHeading").text(e.username),t(),e.messages=v(e),u(e)):($("#fileNotReplacedWarning").show(),$("#fileReplacedLoader").hide(),$("#fileReplacedButton").show())}).fail(function(a,n,s){var o=n+", "+s;console.log("davemail.json failed to load: "+o),$("#signUpReplaceDownload").remove(),$("#signUpButton").show(),$("#signingUpLoader").hide(),$("#fileReplacedButton").show(),$("#fileReplacedLoader").hide(),$("#usernameHeading").text(e.username),t(),e.messages=v(e),u(e)})}function n(e){$("#composeToList li").remove();var a=_.map(e.jsonData.responseJSON.davemail.users,function(e,a){return $(" ").text(a).click(function(n){$("#composeTo").val(a),$("#composeTo").removeClass("invalid"),$("#composePublicKey").val(e.publicKey),$("#composeToListWrapper").hide(),$("#composeSendButton").show()}).appendTo("#composeToList"),a}),n=$("#composeTo"),s=$("input#clearfilter");$("#composeToList").listfilter({filter:n,clearlink:s,alternate:!0,alternateclass:"other"}),$("#composeTo").keyup(function(){$("#composeTo").val().length>0?($("#composeToListWrapper").show(),0==$("#composeToList li:visible").length&&$("#composeToListWrapper").hide(),-1==_.indexOf(a,$("#composeTo").val())?($("#composePublicKey").val(""),$("#composeSendButton").hide()):($("#composePublicKey").val(e.jsonData.responseJSON.davemail.users[$("#composeTo").val()].publicKey),$("#composeSendButton").show())):$("#composeToListWrapper").hide()}).focusout(function(){setTimeout(function(){-1==_.indexOf(a,$("#composeTo").val())?$("#composeTo").addClass("invalid"):($("#composeTo").removeClass("invalid"),$("#composeToListWrapper").hide())},10)}),$("#composePublicKeyButton").click(function(){$(this).prop("checked")?$("#composeShowPublicKey").show():$("#composeShowPublicKey").hide()})}function s(e){_.isObject(e)&&e.preventDefault(),$("#importDavemail").show(),$("nav").hide(),$("#signIn").hide(),$("#signUp").hide(),$("#messages").hide(),$("#signUpReplace").hide(),$("#navSignInButton").parent().removeClass("active"),$("#navSignUpButton").parent().removeClass("active"),$("#navMessagesButton").parent().removeClass("active")}function o(e){_.isObject(e)&&e.preventDefault(),$("#signIn").show(),$("#signUp").hide(),$("#messages").hide(),$("#signUpReplace").hide(),$("#navSignInButton").parent().addClass("active"),$("#navSignUpButton").parent().removeClass("active"),$("#navMessagesButton").parent().removeClass("active")}function i(e){_.isObject(e)&&e.preventDefault(),$("#signUp").show(),$("#signIn").hide(),$("#messages").hide(),$("#navSignUpButton").parent().addClass("active"),$("#navSignInButton").parent().removeClass("active"),$("#navMessagesButton").parent().removeClass("active")}function t(e){_.isObject(e)&&e.preventDefault(),$("#messages").show(),$("#compose").hide(),$("#signIn").hide(),$("#signUp").hide(),$("#signUpReplace").hide(),$("#navMessagesButton").show(),$("#navMessagesButton").parent().addClass("active"),$("#navComposeButton").show(),$("#navComposeButton").parent().removeClass("active"),$("#navSignInButton").parent().removeClass("active"),$("#navSignUpButton").parent().removeClass("active"),$("#navSignOutButton").show(),$("#navSignInButton").hide(),$("#navSignUpButton").hide(),$(".jumbotron").hide()}function l(e){_.isObject(e)&&e.preventDefault(),$("#messages").hide(),$("#compose").show(),$("#signIn").hide(),$("#signUp").hide(),$("#signUpReplace").hide(),$("#navMessagesButton").show(),$("#navMessagesButton").parent().removeClass("active"),$("#navComposeButton").show(),$("#navComposeButton").parent().addClass("active"),$("#navSignInButton").parent().removeClass("active"),$("#navSignUpButton").parent().removeClass("active"),$("#navSignOutButton").show(),$("#navSignInButton").hide(),$("#navSignUpButton").hide(),$(".jumbotron").hide()}function r(e){_.isObject(e)&&e.preventDefault(),$("#signIn").show(),$("#signInButton").show(),$("#messages").hide(),$("#compose").hide(),$("#signUp").hide(),$("#signUpReplace").hide(),$("#navComposeButton").hide(),$("#navMessagesButton").hide(),$("#navSignInButton").parent().addClass("active"),$("#navComposeButton").parent().removeClass("active"),$("#navMessagesButton").parent().removeClass("active"),$("#navSignUpButton").parent().removeClass("active"),$("#navSignInButton").show(),$("#navSignUpButton").show(),$("#navSignOutButton").hide(),$("#composeTo").val(""),$("#composeTo").removeClass("invalid"),$("#composePublicKey").val(""),$("#composeShowPublicKey").hide(),$("#composePublicKeyButton").attr("checked",!1),$(".jumbotron").show()}function d(e){return e.messagesTable.destroy(),e.messagesTable=$("#messagesTable").DataTable({data:[],ordering:!1,columns:[{title:"Message"},{title:"Time"}]}),e.username=void 0,e.password=void 0,e.passwordStrength=void 0,e.publicKey=void 0,e.privateKey=void 0,e.messages=void 0,e}function c(e){var a=e,n=g.encode_utf8(a),s=g.encode_utf8("davemail"),o=g.crypto_scrypt(n,s,Math.pow(2,14),8,1,64);return a=g.to_hex(o),console.log(a),a}function p(e){return e.privateKey=cryptico.generateRSAKey(c(e.password),1536),e.publicKey=cryptico.publicKeyString(e.privateKey),console.log(e.privateKey),console.log(e.publicKey),e}function m(e,a,n){var s=c(a),o=cryptico.encrypt(e.concat(s),n);return o}function v(e){return e.decryptedMessages=new Array,_.map(e.jsonData.responseJSON.davemail.emails,function(a,n){var s=cryptico.decrypt(a.cipher,e.privateKey);if("success"==s.status){var o=moment(a.time).format("MMM Do YY"),i=s.plaintext.substring(0,s.plaintext.length-128);return e.decryptedMessages.push([i,o]),[i,o]}})}function u(e){_.isUndefined(e.decryptedMessages[0])||(e.messagesTable.destroy(),e.messagesTable=$("#messagesTable").DataTable({data:e.decryptedMessages,ordering:!1,columns:[{title:"Message"},{title:"Time"}]}))}window.davemail=new Object,davemail.info="Davemail 2.0.0 by David Apple https://github.com/davidapple/davemail Donate Bitcoin to 13D3A8PP91MLF5VTBQMH5HG76F42RNRF28";var g=scrypt_module_factory();davemail.jsonData=e(),$(document).on("change","#importDavemailFile",function(e){var a=new FileReader;$("#importDavemailButton").hide(),$("#importingLoader").show(),a.onload=function(e){console.log("davemail.json loaded confirmation one");var a=JSON.parse(e.target.result);davemail.jsonData=new Object,davemail.jsonData.responseJSON=a,$("nav").show(),$("#signIn").show(),$("#importDavemail").hide()},a.readAsText(e.target.files[0])}),$("#navSignInButton").click(function(e){o(e)}),$("#navSignUpButton").click(function(e){i(e)}),$("#navMessagesButton").click(function(e){t(e)}),$("#navComposeButton").click(function(e){l(e)}),$("#navSignOutButton").click(function(e){r(e),davemail=d(davemail)}),$("#signUpButtonOnSignIn").click(function(e){i(e)}),davemail.messagesTable=$("#messagesTable").DataTable({data:[],ordering:!1,columns:[{title:"Message"},{title:"Time"}]}),$("#signInButton").click(function(){$("#signInButton").hide(),$("#signingInLoader").show(),davemail.password=$("#signInPassword").val(),davemail.passwordStrength=zxcvbn(davemail.password),davemail.passwordStrength.score<4?setTimeout(function(){$("#passwordWarningSignIn").show(),$("#signInButton").show(),$("#signingInLoader").hide()},100):setTimeout(function(){davemail=p(davemail),_.map(davemail.jsonData.responseJSON.davemail.users,function(e,a){davemail.publicKey==e.publicKey&&($("#usernameHeading").text(a),davemail.username=a)}),$("#signingInLoader").hide(),$("#signIn").hide(),$("#signInPassword").val(""),t(),davemail.messages=v(davemail),u(davemail),n(davemail)},10)}),$("#signUpButton").click(function(){if($("#signUpUsername").val($("#signUpUsername").val().toLowerCase()),davemail.username=$("#signUpUsername").val(),davemail.password=$("#signUpPassword").val(),davemail.passwordStrength=zxcvbn(davemail.password),$("#usernameTakenWarning").hide(),$("#passwordWarning").hide(),davemail.username.length>0){$("#usernameEmptyWarning").hide();var e=_.map(davemail.jsonData.responseJSON.davemail.users,function(e,a){return davemail.username==a.toLowerCase()});_.contains(e,!0)?($("#usernameTakenWarning").show(),$("#passwordWarning").hide(),e=!0):e=!1;var a=/^[a-z0-9]*$/.test(davemail.username);if(a?$("#usernameIllegalWarning").hide():$("#usernameIllegalWarning").show(),a&&!e&&davemail.passwordStrength.score>3)$("#passwordWarning").hide(),$("#signUpButton").hide(),$("#signingUpLoader").show(),setTimeout(function(){davemail=p(davemail);var e=davemail.jsonData.responseJSON.davemail.users,a=davemail.jsonData.responseJSON.davemail.emails,s=davemail.jsonData.responseJSON.davemail.servers;e[davemail.username]={publicKey:davemail.publicKey},davemail.jsonData.responseJSON={davemail:{users:e,emails:a,servers:s}},$("#signUpJson").text(JSON.stringify(davemail.jsonData.responseJSON,null,4));var o="text/json;charset=utf-8,"+encodeURIComponent(JSON.stringify(davemail.jsonData.responseJSON,null,4));$("#signUpUsername").val(""),$("#signUpPassword").val(""),$("#signUp").hide(),$("#signUpReplace").show(),$('Right click here ').appendTo("#signUpDownload"),n(davemail)},100);else{davemail.passwordStrength.score<4&&$("#passwordWarning").show(),$("#passwordWarningText").text(davemail.passwordStrength.feedback.warning);var s=$("#passwordSuggestionsText");s.children().remove(),$.each(davemail.passwordStrength.feedback.suggestions,function(e){var a=$("
").appendTo(s).text(davemail.passwordStrength.feedback.suggestions[e]).appendTo(a)})}}else $("#usernameEmptyWarning").show()}),$("#composeSendButton").click(function(){if(davemail.jsonData.responseJSON.davemail.users[$("#composeTo").val()].publicKey==$("#composePublicKey").val()){$(this).hide(),$("#sendingLoader").show();var e=new Date,a=m($("#composeMessage").val(),e.toISOString(),$("#composePublicKey").val());console.log(a),"success"==a.status&&setTimeout(function(){$("#composeTo").val(""),$("#composePublicKey").val(""),$("#composeMessage").val(""),$("#sendingLoader").hide(),$("#compose").hide(),$("#signUpReplace").show();var n=davemail.jsonData.responseJSON.davemail.users,s=davemail.jsonData.responseJSON.davemail.emails,o=davemail.jsonData.responseJSON.davemail.servers;s.push({time:e.toISOString(),cipher:a.cipher}),davemail.jsonData.responseJSON={davemail:{users:n,emails:s,servers:o}},$("#signUpJson").text(JSON.stringify(davemail.jsonData.responseJSON,null,4));var i="text/json;charset=utf-8,"+encodeURIComponent(JSON.stringify(davemail.jsonData.responseJSON,null,4));$('Right click here ').appendTo("#signUpDownload")},100)}else console.log("fail")}),$("#fileReplacedButton").click(function(){$("#fileReplacedButton").hide(),$("#fileReplacedLoader").show(),setTimeout(function(){a(davemail)},500)})}();
--------------------------------------------------------------------------------
/dist/scripts/plugins.js:
--------------------------------------------------------------------------------
1 | +function(t){"use strict";function e(e){return this.each(function(){var o=t(this),n=o.data("bs.affix"),s="object"==typeof e&&e;n||o.data("bs.affix",n=new i(this,s)),"string"==typeof e&&n[e]()})}var i=function(e,o){this.options=t.extend({},i.DEFAULTS,o),this.$target=t(this.options.target).on("scroll.bs.affix.data-api",t.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",t.proxy(this.checkPositionWithEventLoop,this)),this.$element=t(e),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};i.VERSION="3.3.6",i.RESET="affix affix-top affix-bottom",i.DEFAULTS={offset:0,target:window},i.prototype.getState=function(t,e,i,o){var n=this.$target.scrollTop(),s=this.$element.offset(),a=this.$target.height();if(null!=i&&"top"==this.affixed)return i>n?"top":!1;if("bottom"==this.affixed)return null!=i?n+this.unpin<=s.top?!1:"bottom":t-o>=n+a?!1:"bottom";var r=null==this.affixed,l=r?n:s.top,h=r?a:e;return null!=i&&i>=n?"top":null!=o&&l+h>=t-o?"bottom":!1},i.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(i.RESET).addClass("affix");var t=this.$target.scrollTop(),e=this.$element.offset();return this.pinnedOffset=e.top-t},i.prototype.checkPositionWithEventLoop=function(){setTimeout(t.proxy(this.checkPosition,this),1)},i.prototype.checkPosition=function(){if(this.$element.is(":visible")){var e=this.$element.height(),o=this.options.offset,n=o.top,s=o.bottom,a=Math.max(t(document).height(),t(document.body).height());"object"!=typeof o&&(s=n=o),"function"==typeof n&&(n=o.top(this.$element)),"function"==typeof s&&(s=o.bottom(this.$element));var r=this.getState(a,e,n,s);if(this.affixed!=r){null!=this.unpin&&this.$element.css("top","");var l="affix"+(r?"-"+r:""),h=t.Event(l+".bs.affix");if(this.$element.trigger(h),h.isDefaultPrevented())return;this.affixed=r,this.unpin="bottom"==r?this.getPinnedOffset():null,this.$element.removeClass(i.RESET).addClass(l).trigger(l.replace("affix","affixed")+".bs.affix")}"bottom"==r&&this.$element.offset({top:a-e-s})}};var o=t.fn.affix;t.fn.affix=e,t.fn.affix.Constructor=i,t.fn.affix.noConflict=function(){return t.fn.affix=o,this},t(window).on("load",function(){t('[data-spy="affix"]').each(function(){var i=t(this),o=i.data();o.offset=o.offset||{},null!=o.offsetBottom&&(o.offset.bottom=o.offsetBottom),null!=o.offsetTop&&(o.offset.top=o.offsetTop),e.call(i,o)})})}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var i=t(this),n=i.data("bs.alert");n||i.data("bs.alert",n=new o(this)),"string"==typeof e&&n[e].call(i)})}var i='[data-dismiss="alert"]',o=function(e){t(e).on("click",i,this.close)};o.VERSION="3.3.6",o.TRANSITION_DURATION=150,o.prototype.close=function(e){function i(){a.detach().trigger("closed.bs.alert").remove()}var n=t(this),s=n.attr("data-target");s||(s=n.attr("href"),s=s&&s.replace(/.*(?=#[^\s]*$)/,""));var a=t(s);e&&e.preventDefault(),a.length||(a=n.closest(".alert")),a.trigger(e=t.Event("close.bs.alert")),e.isDefaultPrevented()||(a.removeClass("in"),t.support.transition&&a.hasClass("fade")?a.one("bsTransitionEnd",i).emulateTransitionEnd(o.TRANSITION_DURATION):i())};var n=t.fn.alert;t.fn.alert=e,t.fn.alert.Constructor=o,t.fn.alert.noConflict=function(){return t.fn.alert=n,this},t(document).on("click.bs.alert.data-api",i,o.prototype.close)}(jQuery),+function(t){"use strict";function e(e){var i=e.attr("data-target");i||(i=e.attr("href"),i=i&&/#[A-Za-z]/.test(i)&&i.replace(/.*(?=#[^\s]*$)/,""));var o=i&&t(i);return o&&o.length?o:e.parent()}function i(i){i&&3===i.which||(t(n).remove(),t(s).each(function(){var o=t(this),n=e(o),s={relatedTarget:this};n.hasClass("open")&&(i&&"click"==i.type&&/input|textarea/i.test(i.target.tagName)&&t.contains(n[0],i.target)||(n.trigger(i=t.Event("hide.bs.dropdown",s)),i.isDefaultPrevented()||(o.attr("aria-expanded","false"),n.removeClass("open").trigger(t.Event("hidden.bs.dropdown",s)))))}))}function o(e){return this.each(function(){var i=t(this),o=i.data("bs.dropdown");o||i.data("bs.dropdown",o=new a(this)),"string"==typeof e&&o[e].call(i)})}var n=".dropdown-backdrop",s='[data-toggle="dropdown"]',a=function(e){t(e).on("click.bs.dropdown",this.toggle)};a.VERSION="3.3.6",a.prototype.toggle=function(o){var n=t(this);if(!n.is(".disabled, :disabled")){var s=e(n),a=s.hasClass("open");if(i(),!a){"ontouchstart"in document.documentElement&&!s.closest(".navbar-nav").length&&t(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(t(this)).on("click",i);var r={relatedTarget:this};if(s.trigger(o=t.Event("show.bs.dropdown",r)),o.isDefaultPrevented())return;n.trigger("focus").attr("aria-expanded","true"),s.toggleClass("open").trigger(t.Event("shown.bs.dropdown",r))}return!1}},a.prototype.keydown=function(i){if(/(38|40|27|32)/.test(i.which)&&!/input|textarea/i.test(i.target.tagName)){var o=t(this);if(i.preventDefault(),i.stopPropagation(),!o.is(".disabled, :disabled")){var n=e(o),a=n.hasClass("open");if(!a&&27!=i.which||a&&27==i.which)return 27==i.which&&n.find(s).trigger("focus"),o.trigger("click");var r=" li:not(.disabled):visible a",l=n.find(".dropdown-menu"+r);if(l.length){var h=l.index(i.target);38==i.which&&h>0&&h--,40==i.which&&h
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},i.prototype.init=function(e,i,o){if(this.enabled=!0,this.type=e,this.$element=t(i),this.options=this.getOptions(o),this.$viewport=this.options.viewport&&t(t.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var n=this.options.trigger.split(" "),s=n.length;s--;){var a=n[s];if("click"==a)this.$element.on("click."+this.type,this.options.selector,t.proxy(this.toggle,this));else if("manual"!=a){var r="hover"==a?"mouseenter":"focusin",l="hover"==a?"mouseleave":"focusout";this.$element.on(r+"."+this.type,this.options.selector,t.proxy(this.enter,this)),this.$element.on(l+"."+this.type,this.options.selector,t.proxy(this.leave,this))}}this.options.selector?this._options=t.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},i.prototype.getDefaults=function(){return i.DEFAULTS},i.prototype.getOptions=function(e){return e=t.extend({},this.getDefaults(),this.$element.data(),e),e.delay&&"number"==typeof e.delay&&(e.delay={show:e.delay,hide:e.delay}),e},i.prototype.getDelegateOptions=function(){var e={},i=this.getDefaults();return this._options&&t.each(this._options,function(t,o){i[t]!=o&&(e[t]=o)}),e},i.prototype.enter=function(e){var i=e instanceof this.constructor?e:t(e.currentTarget).data("bs."+this.type);return i||(i=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,i)),e instanceof t.Event&&(i.inState["focusin"==e.type?"focus":"hover"]=!0),i.tip().hasClass("in")||"in"==i.hoverState?void(i.hoverState="in"):(clearTimeout(i.timeout),i.hoverState="in",i.options.delay&&i.options.delay.show?void(i.timeout=setTimeout(function(){"in"==i.hoverState&&i.show()},i.options.delay.show)):i.show())},i.prototype.isInStateTrue=function(){for(var t in this.inState)if(this.inState[t])return!0;return!1},i.prototype.leave=function(e){var i=e instanceof this.constructor?e:t(e.currentTarget).data("bs."+this.type);return i||(i=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,i)),e instanceof t.Event&&(i.inState["focusout"==e.type?"focus":"hover"]=!1),i.isInStateTrue()?void 0:(clearTimeout(i.timeout),i.hoverState="out",i.options.delay&&i.options.delay.hide?void(i.timeout=setTimeout(function(){"out"==i.hoverState&&i.hide()},i.options.delay.hide)):i.hide())},i.prototype.show=function(){var e=t.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(e);var o=t.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(e.isDefaultPrevented()||!o)return;var n=this,s=this.tip(),a=this.getUID(this.type);this.setContent(),s.attr("id",a),this.$element.attr("aria-describedby",a),this.options.animation&&s.addClass("fade");var r="function"==typeof this.options.placement?this.options.placement.call(this,s[0],this.$element[0]):this.options.placement,l=/\s?auto?\s?/i,h=l.test(r);h&&(r=r.replace(l,"")||"top"),s.detach().css({top:0,left:0,display:"block"}).addClass(r).data("bs."+this.type,this),this.options.container?s.appendTo(this.options.container):s.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var d=this.getPosition(),p=s[0].offsetWidth,c=s[0].offsetHeight;if(h){var f=r,u=this.getPosition(this.$viewport);r="bottom"==r&&d.bottom+c>u.bottom?"top":"top"==r&&d.top-cu.width?"left":"left"==r&&d.left-pa.top+a.height&&(n.top=a.top+a.height-l)}else{var h=e.left-s,d=e.left+s+i;ha.right&&(n.left=a.left+a.width-d)}return n},i.prototype.getTitle=function(){var t,e=this.$element,i=this.options;return t=e.attr("data-original-title")||("function"==typeof i.title?i.title.call(e[0]):i.title)},i.prototype.getUID=function(t){do t+=~~(1e6*Math.random());while(document.getElementById(t));return t},i.prototype.tip=function(){if(!this.$tip&&(this.$tip=t(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},i.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},i.prototype.enable=function(){this.enabled=!0},i.prototype.disable=function(){this.enabled=!1},i.prototype.toggleEnabled=function(){this.enabled=!this.enabled},i.prototype.toggle=function(e){var i=this;e&&(i=t(e.currentTarget).data("bs."+this.type),i||(i=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,i))),e?(i.inState.click=!i.inState.click,i.isInStateTrue()?i.enter(i):i.leave(i)):i.tip().hasClass("in")?i.leave(i):i.enter(i)},i.prototype.destroy=function(){var t=this;clearTimeout(this.timeout),this.hide(function(){t.$element.off("."+t.type).removeData("bs."+t.type),t.$tip&&t.$tip.detach(),t.$tip=null,t.$arrow=null,t.$viewport=null})};var o=t.fn.tooltip;t.fn.tooltip=e,t.fn.tooltip.Constructor=i,t.fn.tooltip.noConflict=function(){return t.fn.tooltip=o,this}}(jQuery),+function(t){"use strict";function e(e,o){return this.each(function(){var n=t(this),s=n.data("bs.modal"),a=t.extend({},i.DEFAULTS,n.data(),"object"==typeof e&&e);s||n.data("bs.modal",s=new i(this,a)),"string"==typeof e?s[e](o):a.show&&s.show(o)})}var i=function(e,i){this.options=i,this.$body=t(document.body),this.$element=t(e),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,t.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};i.VERSION="3.3.6",i.TRANSITION_DURATION=300,i.BACKDROP_TRANSITION_DURATION=150,i.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},i.prototype.toggle=function(t){return this.isShown?this.hide():this.show(t)},i.prototype.show=function(e){var o=this,n=t.Event("show.bs.modal",{relatedTarget:e});this.$element.trigger(n),this.isShown||n.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',t.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){o.$element.one("mouseup.dismiss.bs.modal",function(e){t(e.target).is(o.$element)&&(o.ignoreBackdropClick=!0)})}),this.backdrop(function(){var n=t.support.transition&&o.$element.hasClass("fade");o.$element.parent().length||o.$element.appendTo(o.$body),o.$element.show().scrollTop(0),o.adjustDialog(),n&&o.$element[0].offsetWidth,o.$element.addClass("in"),o.enforceFocus();var s=t.Event("shown.bs.modal",{relatedTarget:e});n?o.$dialog.one("bsTransitionEnd",function(){o.$element.trigger("focus").trigger(s)}).emulateTransitionEnd(i.TRANSITION_DURATION):o.$element.trigger("focus").trigger(s)}))},i.prototype.hide=function(e){e&&e.preventDefault(),e=t.Event("hide.bs.modal"),this.$element.trigger(e),this.isShown&&!e.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),t(document).off("focusin.bs.modal"),this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),t.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",t.proxy(this.hideModal,this)).emulateTransitionEnd(i.TRANSITION_DURATION):this.hideModal())},i.prototype.enforceFocus=function(){t(document).off("focusin.bs.modal").on("focusin.bs.modal",t.proxy(function(t){this.$element[0]===t.target||this.$element.has(t.target).length||this.$element.trigger("focus")},this))},i.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",t.proxy(function(t){27==t.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},i.prototype.resize=function(){this.isShown?t(window).on("resize.bs.modal",t.proxy(this.handleUpdate,this)):t(window).off("resize.bs.modal")},i.prototype.hideModal=function(){var t=this;this.$element.hide(),this.backdrop(function(){t.$body.removeClass("modal-open"),t.resetAdjustments(),t.resetScrollbar(),t.$element.trigger("hidden.bs.modal")})},i.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},i.prototype.backdrop=function(e){var o=this,n=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var s=t.support.transition&&n;if(this.$backdrop=t(document.createElement("div")).addClass("modal-backdrop "+n).appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",t.proxy(function(t){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(t.target===t.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),s&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!e)return;s?this.$backdrop.one("bsTransitionEnd",e).emulateTransitionEnd(i.BACKDROP_TRANSITION_DURATION):e()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var a=function(){o.removeBackdrop(),e&&e()};t.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",a).emulateTransitionEnd(i.BACKDROP_TRANSITION_DURATION):a()}else e&&e()},i.prototype.handleUpdate=function(){this.adjustDialog()},i.prototype.adjustDialog=function(){var t=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&t?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!t?this.scrollbarWidth:""})},i.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},i.prototype.checkScrollbar=function(){var t=window.innerWidth;if(!t){var e=document.documentElement.getBoundingClientRect();t=e.right-Math.abs(e.left)}this.bodyIsOverflowing=document.body.clientWidth
'}),i.prototype=t.extend({},t.fn.tooltip.Constructor.prototype),i.prototype.constructor=i,i.prototype.getDefaults=function(){return i.DEFAULTS},i.prototype.setContent=function(){var t=this.tip(),e=this.getTitle(),i=this.getContent();t.find(".popover-title")[this.options.html?"html":"text"](e),t.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof i?"html":"append":"text"](i),t.removeClass("fade top bottom left right in"),t.find(".popover-title").html()||t.find(".popover-title").hide()},i.prototype.hasContent=function(){return this.getTitle()||this.getContent()},i.prototype.getContent=function(){var t=this.$element,e=this.options;return t.attr("data-content")||("function"==typeof e.content?e.content.call(t[0]):e.content)},i.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var o=t.fn.popover;t.fn.popover=e,t.fn.popover.Constructor=i,t.fn.popover.noConflict=function(){return t.fn.popover=o,this}}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),n=o.data("bs.carousel"),s=t.extend({},i.DEFAULTS,o.data(),"object"==typeof e&&e),a="string"==typeof e?e:s.slide;n||o.data("bs.carousel",n=new i(this,s)),"number"==typeof e?n.to(e):a?n[a]():s.interval&&n.pause().cycle()})}var i=function(e,i){this.$element=t(e),this.$indicators=this.$element.find(".carousel-indicators"),this.options=i,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",t.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",t.proxy(this.pause,this)).on("mouseleave.bs.carousel",t.proxy(this.cycle,this))};i.VERSION="3.3.6",i.TRANSITION_DURATION=600,i.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},i.prototype.keydown=function(t){if(!/input|textarea/i.test(t.target.tagName)){switch(t.which){case 37:this.prev();break;case 39:this.next();break;default:return}t.preventDefault()}},i.prototype.cycle=function(e){return e||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(t.proxy(this.next,this),this.options.interval)),this},i.prototype.getItemIndex=function(t){return this.$items=t.parent().children(".item"),this.$items.index(t||this.$active)},i.prototype.getItemForDirection=function(t,e){var i=this.getItemIndex(e),o="prev"==t&&0===i||"next"==t&&i==this.$items.length-1;if(o&&!this.options.wrap)return e;var n="prev"==t?-1:1,s=(i+n)%this.$items.length;return this.$items.eq(s)},i.prototype.to=function(t){var e=this,i=this.getItemIndex(this.$active=this.$element.find(".item.active"));return t>this.$items.length-1||0>t?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){e.to(t)}):i==t?this.pause().cycle():this.slide(t>i?"next":"prev",this.$items.eq(t))},i.prototype.pause=function(e){return e||(this.paused=!0),this.$element.find(".next, .prev").length&&t.support.transition&&(this.$element.trigger(t.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},i.prototype.next=function(){return this.sliding?void 0:this.slide("next")},i.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},i.prototype.slide=function(e,o){var n=this.$element.find(".item.active"),s=o||this.getItemForDirection(e,n),a=this.interval,r="next"==e?"left":"right",l=this;if(s.hasClass("active"))return this.sliding=!1;var h=s[0],d=t.Event("slide.bs.carousel",{relatedTarget:h,direction:r});if(this.$element.trigger(d),!d.isDefaultPrevented()){if(this.sliding=!0,a&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var p=t(this.$indicators.children()[this.getItemIndex(s)]);p&&p.addClass("active")}var c=t.Event("slid.bs.carousel",{relatedTarget:h,direction:r});return t.support.transition&&this.$element.hasClass("slide")?(s.addClass(e),s[0].offsetWidth,n.addClass(r),s.addClass(r),n.one("bsTransitionEnd",function(){s.removeClass([e,r].join(" ")).addClass("active"),n.removeClass(["active",r].join(" ")),l.sliding=!1,setTimeout(function(){l.$element.trigger(c)},0)}).emulateTransitionEnd(i.TRANSITION_DURATION)):(n.removeClass("active"),s.addClass("active"),this.sliding=!1,this.$element.trigger(c)),a&&this.cycle(),this}};var o=t.fn.carousel;t.fn.carousel=e,t.fn.carousel.Constructor=i,t.fn.carousel.noConflict=function(){return t.fn.carousel=o,this};var n=function(i){var o,n=t(this),s=t(n.attr("data-target")||(o=n.attr("href"))&&o.replace(/.*(?=#[^\s]+$)/,""));if(s.hasClass("carousel")){var a=t.extend({},s.data(),n.data()),r=n.attr("data-slide-to");r&&(a.interval=!1),e.call(s,a),r&&s.data("bs.carousel").to(r),i.preventDefault()}};t(document).on("click.bs.carousel.data-api","[data-slide]",n).on("click.bs.carousel.data-api","[data-slide-to]",n),t(window).on("load",function(){t('[data-ride="carousel"]').each(function(){var i=t(this);e.call(i,i.data())})})}(jQuery),+function(t){"use strict";function e(i,o){this.$body=t(document.body),this.$scrollElement=t(t(i).is(document.body)?window:i),this.options=t.extend({},e.DEFAULTS,o),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",t.proxy(this.process,this)),this.refresh(),this.process()}function i(i){return this.each(function(){var o=t(this),n=o.data("bs.scrollspy"),s="object"==typeof i&&i;n||o.data("bs.scrollspy",n=new e(this,s)),"string"==typeof i&&n[i]()})}e.VERSION="3.3.6",e.DEFAULTS={offset:10},e.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},e.prototype.refresh=function(){var e=this,i="offset",o=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),t.isWindow(this.$scrollElement[0])||(i="position",o=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var e=t(this),n=e.data("target")||e.attr("href"),s=/^#./.test(n)&&t(n);return s&&s.length&&s.is(":visible")&&[[s[i]().top+o,n]]||null}).sort(function(t,e){return t[0]-e[0]}).each(function(){e.offsets.push(this[0]),e.targets.push(this[1])})},e.prototype.process=function(){var t,e=this.$scrollElement.scrollTop()+this.options.offset,i=this.getScrollHeight(),o=this.options.offset+i-this.$scrollElement.height(),n=this.offsets,s=this.targets,a=this.activeTarget;if(this.scrollHeight!=i&&this.refresh(),e>=o)return a!=(t=s[s.length-1])&&this.activate(t);if(a&&e=n[t]&&(void 0===n[t+1]||e .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),e.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),r?(e[0].offsetWidth,e.addClass("in")):e.removeClass("fade"),e.parent(".dropdown-menu").length&&e.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),n&&n()}var a=o.find("> .active"),r=n&&t.support.transition&&(a.length&&a.hasClass("fade")||!!o.find("> .fade").length);a.length&&r?a.one("bsTransitionEnd",s).emulateTransitionEnd(i.TRANSITION_DURATION):s(),a.removeClass("in")};var o=t.fn.tab;t.fn.tab=e,t.fn.tab.Constructor=i,t.fn.tab.noConflict=function(){return t.fn.tab=o,this};var n=function(i){i.preventDefault(),e.call(t(this),"show")};t(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',n).on("click.bs.tab.data-api",'[data-toggle="pill"]',n)}(jQuery);
--------------------------------------------------------------------------------
/dist/scripts/vendor/modernizr.js:
--------------------------------------------------------------------------------
1 | window.Modernizr=function(e,t,n){function r(e){b.cssText=e}function o(e,t){return r(S.join(e+";")+(t||""))}function a(e,t){return typeof e===t}function i(e,t){return!!~(""+e).indexOf(t)}function c(e,t){for(var r in e){var o=e[r];if(!i(o,"-")&&b[o]!==n)return"pfx"==t?o:!0}return!1}function s(e,t,r){for(var o in e){var i=t[e[o]];if(i!==n)return r===!1?e[o]:a(i,"function")?i.bind(r||t):i}return!1}function u(e,t,n){var r=e.charAt(0).toUpperCase()+e.slice(1),o=(e+" "+k.join(r+" ")+r).split(" ");return a(t,"string")||a(t,"undefined")?c(o,t):(o=(e+" "+T.join(r+" ")+r).split(" "),s(o,t,n))}function l(){p.input=function(n){for(var r=0,o=n.length;o>r;r++)j[n[r]]=!!(n[r]in E);return j.list&&(j.list=!(!t.createElement("datalist")||!e.HTMLDataListElement)),j}("autocomplete autofocus list placeholder max min multiple pattern required step".split(" ")),p.inputtypes=function(e){for(var r,o,a,i=0,c=e.length;c>i;i++)E.setAttribute("type",o=e[i]),r="text"!==E.type,r&&(E.value=x,E.style.cssText="position:absolute;visibility:hidden;",/^range$/.test(o)&&E.style.WebkitAppearance!==n?(g.appendChild(E),a=t.defaultView,r=a.getComputedStyle&&"textfield"!==a.getComputedStyle(E,null).WebkitAppearance&&0!==E.offsetHeight,g.removeChild(E)):/^(search|tel)$/.test(o)||(r=/^(url|email)$/.test(o)?E.checkValidity&&E.checkValidity()===!1:E.value!=x)),P[e[i]]=!!r;return P}("search tel url email datetime date month week time datetime-local number range color".split(" "))}var d,f,m="2.8.3",p={},h=!0,g=t.documentElement,v="modernizr",y=t.createElement(v),b=y.style,E=t.createElement("input"),x=":)",w={}.toString,S=" -webkit- -moz- -o- -ms- ".split(" "),C="Webkit Moz O ms",k=C.split(" "),T=C.toLowerCase().split(" "),N={svg:"http://www.w3.org/2000/svg"},M={},P={},j={},$=[],D=$.slice,F=function(e,n,r,o){var a,i,c,s,u=t.createElement("div"),l=t.body,d=l||t.createElement("body");if(parseInt(r,10))for(;r--;)c=t.createElement("div"),c.id=o?o[r]:v+(r+1),u.appendChild(c);return a=["",'"].join(""),u.id=v,(l?u:d).innerHTML+=a,d.appendChild(u),l||(d.style.background="",d.style.overflow="hidden",s=g.style.overflow,g.style.overflow="hidden",g.appendChild(d)),i=n(u,e),l?u.parentNode.removeChild(u):(d.parentNode.removeChild(d),g.style.overflow=s),!!i},z=function(t){var n=e.matchMedia||e.msMatchMedia;if(n)return n(t)&&n(t).matches||!1;var r;return F("@media "+t+" { #"+v+" { position: absolute; } }",function(t){r="absolute"==(e.getComputedStyle?getComputedStyle(t,null):t.currentStyle).position}),r},A=function(){function e(e,o){o=o||t.createElement(r[e]||"div"),e="on"+e;var i=e in o;return i||(o.setAttribute||(o=t.createElement("div")),o.setAttribute&&o.removeAttribute&&(o.setAttribute(e,""),i=a(o[e],"function"),a(o[e],"undefined")||(o[e]=n),o.removeAttribute(e))),o=null,i}var r={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return e}(),L={}.hasOwnProperty;f=a(L,"undefined")||a(L.call,"undefined")?function(e,t){return t in e&&a(e.constructor.prototype[t],"undefined")}:function(e,t){return L.call(e,t)},Function.prototype.bind||(Function.prototype.bind=function(e){var t=this;if("function"!=typeof t)throw new TypeError;var n=D.call(arguments,1),r=function(){if(this instanceof r){var o=function(){};o.prototype=t.prototype;var a=new o,i=t.apply(a,n.concat(D.call(arguments)));return Object(i)===i?i:a}return t.apply(e,n.concat(D.call(arguments)))};return r}),M.flexbox=function(){return u("flexWrap")},M.flexboxlegacy=function(){return u("boxDirection")},M.canvas=function(){var e=t.createElement("canvas");return!(!e.getContext||!e.getContext("2d"))},M.canvastext=function(){return!(!p.canvas||!a(t.createElement("canvas").getContext("2d").fillText,"function"))},M.webgl=function(){return!!e.WebGLRenderingContext},M.touch=function(){var n;return"ontouchstart"in e||e.DocumentTouch&&t instanceof DocumentTouch?n=!0:F(["@media (",S.join("touch-enabled),("),v,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(e){n=9===e.offsetTop}),n},M.geolocation=function(){return"geolocation"in navigator},M.postmessage=function(){return!!e.postMessage},M.websqldatabase=function(){return!!e.openDatabase},M.indexedDB=function(){return!!u("indexedDB",e)},M.hashchange=function(){return A("hashchange",e)&&(t.documentMode===n||t.documentMode>7)},M.history=function(){return!(!e.history||!history.pushState)},M.draganddrop=function(){var e=t.createElement("div");return"draggable"in e||"ondragstart"in e&&"ondrop"in e},M.websockets=function(){return"WebSocket"in e||"MozWebSocket"in e},M.rgba=function(){return r("background-color:rgba(150,255,150,.5)"),i(b.backgroundColor,"rgba")},M.hsla=function(){return r("background-color:hsla(120,40%,100%,.5)"),i(b.backgroundColor,"rgba")||i(b.backgroundColor,"hsla")},M.multiplebgs=function(){return r("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(b.background)},M.backgroundsize=function(){return u("backgroundSize")},M.borderimage=function(){return u("borderImage")},M.borderradius=function(){return u("borderRadius")},M.boxshadow=function(){return u("boxShadow")},M.textshadow=function(){return""===t.createElement("div").style.textShadow},M.opacity=function(){return o("opacity:.55"),/^0.55$/.test(b.opacity)},M.cssanimations=function(){return u("animationName")},M.csscolumns=function(){return u("columnCount")},M.cssgradients=function(){var e="background-image:",t="gradient(linear,left top,right bottom,from(#9f9),to(white));",n="linear-gradient(left top,#9f9, white);";return r((e+"-webkit- ".split(" ").join(t+e)+S.join(n+e)).slice(0,-e.length)),i(b.backgroundImage,"gradient")},M.cssreflections=function(){return u("boxReflect")},M.csstransforms=function(){return!!u("transform")},M.csstransforms3d=function(){var e=!!u("perspective");return e&&"webkitPerspective"in g.style&&F("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(t,n){e=9===t.offsetLeft&&3===t.offsetHeight}),e},M.csstransitions=function(){return u("transition")},M.fontface=function(){var e;return F('@font-face {font-family:"font";src:url("https://")}',function(n,r){var o=t.getElementById("smodernizr"),a=o.sheet||o.styleSheet,i=a?a.cssRules&&a.cssRules[0]?a.cssRules[0].cssText:a.cssText||"":"";e=/src/i.test(i)&&0===i.indexOf(r.split(" ")[0])}),e},M.generatedcontent=function(){var e;return F(["#",v,"{font:0/0 a}#",v,':after{content:"',x,'";visibility:hidden;font:3px/1 a}'].join(""),function(t){e=t.offsetHeight>=3}),e},M.video=function(){var e=t.createElement("video"),n=!1;try{(n=!!e.canPlayType)&&(n=new Boolean(n),n.ogg=e.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),n.h264=e.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),n.webm=e.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,""))}catch(r){}return n},M.audio=function(){var e=t.createElement("audio"),n=!1;try{(n=!!e.canPlayType)&&(n=new Boolean(n),n.ogg=e.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),n.mp3=e.canPlayType("audio/mpeg;").replace(/^no$/,""),n.wav=e.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),n.m4a=(e.canPlayType("audio/x-m4a;")||e.canPlayType("audio/aac;")).replace(/^no$/,""))}catch(r){}return n},M.localstorage=function(){try{return localStorage.setItem(v,v),localStorage.removeItem(v),!0}catch(e){return!1}},M.sessionstorage=function(){try{return sessionStorage.setItem(v,v),sessionStorage.removeItem(v),!0}catch(e){return!1}},M.webworkers=function(){return!!e.Worker},M.applicationcache=function(){return!!e.applicationCache},M.svg=function(){return!!t.createElementNS&&!!t.createElementNS(N.svg,"svg").createSVGRect},M.inlinesvg=function(){var e=t.createElement("div");return e.innerHTML=" ",(e.firstChild&&e.firstChild.namespaceURI)==N.svg},M.smil=function(){return!!t.createElementNS&&/SVGAnimate/.test(w.call(t.createElementNS(N.svg,"animate")))},M.svgclippaths=function(){return!!t.createElementNS&&/SVGClipPath/.test(w.call(t.createElementNS(N.svg,"clipPath")))};for(var H in M)f(M,H)&&(d=H.toLowerCase(),p[d]=M[H](),$.push((p[d]?"":"no-")+d));return p.input||l(),p.addTest=function(e,t){if("object"==typeof e)for(var r in e)f(e,r)&&p.addTest(r,e[r]);else{if(e=e.toLowerCase(),p[e]!==n)return p;t="function"==typeof t?t():t,"undefined"!=typeof h&&h&&(g.className+=" "+(t?"":"no-")+e),p[e]=t}return p},r(""),y=E=null,function(e,t){function n(e,t){var n=e.createElement("p"),r=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x",r.insertBefore(n.lastChild,r.firstChild)}function r(){var e=y.elements;return"string"==typeof e?e.split(" "):e}function o(e){var t=v[e[h]];return t||(t={},g++,e[h]=g,v[g]=t),t}function a(e,n,r){if(n||(n=t),l)return n.createElement(e);r||(r=o(n));var a;return a=r.cache[e]?r.cache[e].cloneNode():p.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!a.canHaveChildren||m.test(e)||a.tagUrn?a:r.frag.appendChild(a)}function i(e,n){if(e||(e=t),l)return e.createDocumentFragment();n=n||o(e);for(var a=n.frag.cloneNode(),i=0,c=r(),s=c.length;s>i;i++)a.createElement(c[i]);return a}function c(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return y.shivMethods?a(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+r().join().replace(/[\w\-]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(y,t.frag)}function s(e){e||(e=t);var r=o(e);return!y.shivCSS||u||r.hasCSS||(r.hasCSS=!!n(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||c(e,r),e}var u,l,d="3.7.0",f=e.html5||{},m=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,h="_html5shiv",g=0,v={};!function(){try{var e=t.createElement("a");e.innerHTML=" ",u="hidden"in e,l=1==e.childNodes.length||function(){t.createElement("a");var e=t.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(n){u=!0,l=!0}}();var y={elements:f.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:d,shivCSS:f.shivCSS!==!1,supportsUnknownElements:l,shivMethods:f.shivMethods!==!1,type:"default",shivDocument:s,createElement:a,createDocumentFragment:i};e.html5=y,s(t)}(this,t),p._version=m,p._prefixes=S,p._domPrefixes=T,p._cssomPrefixes=k,p.mq=z,p.hasEvent=A,p.testProp=function(e){return c([e])},p.testAllProps=u,p.testStyles=F,p.prefixed=function(e,t,n){return t?u(e,t,n):u(e,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(h?" js "+$.join(" "):""),p}(this,this.document);
--------------------------------------------------------------------------------
/dist/styles/vendor.css:
--------------------------------------------------------------------------------
1 | table.dataTable{clear:both;margin-top:6px!important;margin-bottom:6px!important;max-width:none!important}table.dataTable td,table.dataTable th{box-sizing:content-box}table.dataTable td.dataTables_empty,table.dataTable th.dataTables_empty{text-align:center}table.dataTable.nowrap td,table.dataTable.nowrap th{white-space:nowrap}div.dataTables_wrapper div.dataTables_length label{font-weight:400;text-align:left;white-space:nowrap}div.dataTables_wrapper div.dataTables_length select{width:75px;display:inline-block}div.dataTables_wrapper div.dataTables_filter{text-align:right}div.dataTables_wrapper div.dataTables_filter label{font-weight:400;white-space:nowrap;text-align:left}div.dataTables_wrapper div.dataTables_filter input{margin-left:.5em;display:inline-block;width:auto}div.dataTables_wrapper div.dataTables_info{padding-top:8px;white-space:nowrap}div.dataTables_wrapper div.dataTables_paginate{margin:0;white-space:nowrap;text-align:right}div.dataTables_wrapper div.dataTables_paginate ul.pagination{margin:2px 0;white-space:nowrap}div.dataTables_wrapper div.dataTables_processing{position:absolute;top:50%;left:50%;width:200px;margin-left:-100px;margin-top:-26px;text-align:center;padding:1em 0}table.dataTable thead>tr>td.sorting,table.dataTable thead>tr>td.sorting_asc,table.dataTable thead>tr>td.sorting_desc,table.dataTable thead>tr>th.sorting,table.dataTable thead>tr>th.sorting_asc,table.dataTable thead>tr>th.sorting_desc{padding-right:30px}table.dataTable thead>tr>td:active,table.dataTable thead>tr>th:active{outline:none}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_asc_disabled,table.dataTable thead .sorting_desc,table.dataTable thead .sorting_desc_disabled{cursor:pointer;position:relative}table.dataTable thead .sorting:after,table.dataTable thead .sorting_asc:after,table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc:after,table.dataTable thead .sorting_desc_disabled:after{position:absolute;bottom:8px;right:8px;display:block;font-family:Glyphicons Halflings;opacity:.5}table.dataTable thead .sorting:after{opacity:.2;content:"\e150"}table.dataTable thead .sorting_asc:after{content:"\e155"}table.dataTable thead .sorting_desc:after{content:"\e156"}table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:after{color:#eee}div.dataTables_scrollHead table.dataTable{margin-bottom:0!important}div.dataTables_scrollBody table{border-top:none;margin-top:0!important;margin-bottom:0!important}div.dataTables_scrollBody table thead .sorting:after,div.dataTables_scrollBody table thead .sorting_asc:after,div.dataTables_scrollBody table thead .sorting_desc:after{display:none}div.dataTables_scrollBody table tbody tr:first-child td,div.dataTables_scrollBody table tbody tr:first-child th{border-top:none}div.dataTables_scrollFoot table{margin-top:0!important;border-top:none}@media screen and (max-width:767px){div.dataTables_wrapper div.dataTables_filter,div.dataTables_wrapper div.dataTables_info,div.dataTables_wrapper div.dataTables_length,div.dataTables_wrapper div.dataTables_paginate{text-align:center}}table.dataTable.table-condensed>thead>tr>th{padding-right:20px}table.dataTable.table-condensed .sorting:after,table.dataTable.table-condensed .sorting_asc:after,table.dataTable.table-condensed .sorting_desc:after{top:6px;right:6px}table.table-bordered.dataTable{border-collapse:separate!important}table.table-bordered.dataTable td,table.table-bordered.dataTable th{border-left-width:0}table.table-bordered.dataTable td:last-child,table.table-bordered.dataTable th:last-child{border-right-width:0}div.dataTables_scrollHead table.table-bordered,table.table-bordered.dataTable tbody td,table.table-bordered.dataTable tbody th{border-bottom-width:0}div.table-responsive>div.dataTables_wrapper>div.row{margin:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^=col-]:first-child{padding-left:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^=col-]:last-child{padding-right:0}
--------------------------------------------------------------------------------
/gulpfile.babel.js:
--------------------------------------------------------------------------------
1 | // generated on 2016-04-02 using generator-webapp 2.0.0
2 | import gulp from 'gulp';
3 | import gulpLoadPlugins from 'gulp-load-plugins';
4 | import browserSync from 'browser-sync';
5 | import del from 'del';
6 | import {stream as wiredep} from 'wiredep';
7 |
8 | const $ = gulpLoadPlugins();
9 | const reload = browserSync.reload;
10 |
11 | gulp.task('styles', () => {
12 | return gulp.src('app/styles/*.scss')
13 | .pipe($.plumber())
14 | .pipe($.sourcemaps.init())
15 | .pipe($.sass.sync({
16 | outputStyle: 'expanded',
17 | precision: 10,
18 | includePaths: ['.']
19 | }).on('error', $.sass.logError))
20 | .pipe($.autoprefixer({browsers: ['> 1%', 'last 2 versions', 'Firefox ESR']}))
21 | .pipe($.sourcemaps.write())
22 | .pipe(gulp.dest('.tmp/styles'))
23 | .pipe(reload({stream: true}));
24 | });
25 |
26 | gulp.task('scripts', () => {
27 | return gulp.src('app/scripts/**/*.js')
28 | .pipe($.plumber())
29 | .pipe($.sourcemaps.init())
30 | .pipe($.babel())
31 | .pipe($.sourcemaps.write('.'))
32 | .pipe(gulp.dest('.tmp/scripts'))
33 | .pipe(reload({stream: true}));
34 | });
35 |
36 | function lint(files, options) {
37 | return () => {
38 | return gulp.src(files)
39 | .pipe(reload({stream: true, once: true}))
40 | .pipe($.eslint(options))
41 | .pipe($.eslint.format())
42 | .pipe($.if(!browserSync.active, $.eslint.failAfterError()));
43 | };
44 | }
45 | const testLintOptions = {
46 | env: {
47 | mocha: true
48 | }
49 | };
50 |
51 | gulp.task('lint', lint('app/scripts/**/*.js'));
52 | gulp.task('lint:test', lint('test/spec/**/*.js', testLintOptions));
53 |
54 | gulp.task('html', ['styles', 'scripts'], () => {
55 | return gulp.src('app/*.html')
56 | .pipe($.useref({searchPath: ['.tmp', 'app', '.']}))
57 | .pipe($.if('*.js', $.uglify()))
58 | .pipe($.if('*.css', $.cssnano()))
59 | .pipe($.if('*.html', $.htmlmin({collapseWhitespace: true})))
60 | .pipe(gulp.dest('dist'));
61 | });
62 |
63 | gulp.task('images', () => {
64 | return gulp.src('app/images/**/*')
65 | .pipe($.cache($.imagemin({
66 | progressive: true,
67 | interlaced: true,
68 | // don't remove IDs from SVGs, they are often used
69 | // as hooks for embedding and styling
70 | svgoPlugins: [{cleanupIDs: false}]
71 | })))
72 | .pipe(gulp.dest('dist/images'));
73 | });
74 |
75 | gulp.task('fonts', () => {
76 | return gulp.src(require('main-bower-files')('**/*.{eot,svg,ttf,woff,woff2}', function (err) {})
77 | .concat('app/fonts/**/*'))
78 | .pipe(gulp.dest('.tmp/fonts'))
79 | .pipe(gulp.dest('dist/fonts'));
80 | });
81 |
82 | gulp.task('extras', () => {
83 | return gulp.src([
84 | 'app/*.*',
85 | '!app/*.html'
86 | ], {
87 | dot: true
88 | }).pipe(gulp.dest('dist'));
89 | });
90 |
91 | gulp.task('clean', del.bind(null, ['.tmp', 'dist']));
92 |
93 | gulp.task('serve', ['styles', 'scripts', 'fonts'], () => {
94 | browserSync({
95 | notify: false,
96 | port: 9000,
97 | server: {
98 | baseDir: ['.tmp', 'app'],
99 | routes: {
100 | '/bower_components': 'bower_components'
101 | }
102 | }
103 | });
104 |
105 | gulp.watch([
106 | 'app/*.html',
107 | 'app/images/**/*',
108 | '.tmp/fonts/**/*'
109 | ]).on('change', reload);
110 |
111 | gulp.watch('app/styles/**/*.scss', ['styles']);
112 | gulp.watch('app/scripts/**/*.js', ['scripts']);
113 | gulp.watch('app/fonts/**/*', ['fonts']);
114 | gulp.watch('bower.json', ['wiredep', 'fonts']);
115 | });
116 |
117 | gulp.task('serve:dist', () => {
118 | browserSync({
119 | notify: false,
120 | port: 9000,
121 | server: {
122 | baseDir: ['dist']
123 | }
124 | });
125 | });
126 |
127 | gulp.task('serve:test', ['scripts'], () => {
128 | browserSync({
129 | notify: false,
130 | port: 9000,
131 | ui: false,
132 | server: {
133 | baseDir: 'test',
134 | routes: {
135 | '/scripts': '.tmp/scripts',
136 | '/bower_components': 'bower_components'
137 | }
138 | }
139 | });
140 |
141 | gulp.watch('app/scripts/**/*.js', ['scripts']);
142 | gulp.watch('test/spec/**/*.js').on('change', reload);
143 | gulp.watch('test/spec/**/*.js', ['lint:test']);
144 | });
145 |
146 | // inject bower components
147 | gulp.task('wiredep', () => {
148 | gulp.src('app/styles/*.scss')
149 | .pipe(wiredep({
150 | ignorePath: /^(\.\.\/)+/
151 | }))
152 | .pipe(gulp.dest('app/styles'));
153 |
154 | gulp.src('app/*.html')
155 | .pipe(wiredep({
156 | exclude: ['bootstrap-sass'],
157 | ignorePath: /^(\.\.\/)*\.\./
158 | }))
159 | .pipe(gulp.dest('app'));
160 | });
161 |
162 | gulp.task('build', ['lint', 'html', 'images', 'fonts', 'extras'], () => {
163 | return gulp.src('dist/**/*').pipe($.size({title: 'build', gzip: true}));
164 | });
165 |
166 | gulp.task('default', ['clean'], () => {
167 | gulp.start('build');
168 | });
169 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "davemail",
3 | "version": "2.0.0",
4 | "description": "Decentralised, encrypted, anonymous, offline messaging platform for git.",
5 | "author": "David Apple ",
6 | "license": "MIT",
7 | "private": false,
8 | "engines": {
9 | "node": ">=0.12.0"
10 | },
11 | "devDependencies": {
12 | "babel-core": "^6.4.0",
13 | "babel-preset-es2015": "^6.3.13",
14 | "browser-sync": "^2.2.1",
15 | "del": "^1.1.1",
16 | "grunt": "^0.4.5",
17 | "grunt-contrib-concat": "^1.0.0",
18 | "gulp": "^3.9.0",
19 | "gulp-autoprefixer": "^3.0.1",
20 | "gulp-babel": "^6.1.1",
21 | "gulp-cache": "^0.4.2",
22 | "gulp-cssnano": "^2.0.0",
23 | "gulp-eslint": "^0.13.2",
24 | "gulp-htmlmin": "^1.3.0",
25 | "gulp-if": "^1.2.5",
26 | "gulp-imagemin": "^2.2.1",
27 | "gulp-load-plugins": "^0.10.0",
28 | "gulp-plumber": "^1.0.1",
29 | "gulp-sass": "^2.0.0",
30 | "gulp-size": "^1.2.1",
31 | "gulp-sourcemaps": "^1.5.0",
32 | "gulp-uglify": "^1.1.0",
33 | "gulp-useref": "^3.0.0",
34 | "main-bower-files": "^2.5.0",
35 | "wiredep": "^2.2.2"
36 | },
37 | "eslintConfig": {
38 | "env": {
39 | "es6": true,
40 | "node": true,
41 | "browser": true
42 | },
43 | "rules": {
44 | "quotes": [
45 | 2,
46 | "single"
47 | ],
48 | "eqeqeq": "warn",
49 | "strict": "off"
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Mocha Spec Runner
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
18 |
19 |
20 |
21 |
22 |
23 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/test/spec/test.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | 'use strict';
3 |
4 | describe('Give it some context', function () {
5 | describe('maybe a bit more context here', function () {
6 | it('should run here few assertions', function () {
7 |
8 | });
9 | });
10 | });
11 | })();
12 |
--------------------------------------------------------------------------------