├── .gitignore ├── LICENSE ├── README.md ├── config.xml ├── hooks ├── README.md └── after_prepare │ └── 010_add_platform_class.js ├── ionic.config.json ├── package.json ├── src ├── app │ ├── app.component.ts │ ├── app.html │ ├── app.module.ts │ └── main.ts ├── assets │ ├── icon │ │ └── favicon.ico │ ├── js │ │ ├── amazon-cognito-identity.min.js │ │ ├── aws-cognito-sdk.min.js │ │ ├── aws-sdk-2.7.5.min.js │ │ ├── aws-sdk-mobile-analytics.min.js │ │ ├── chardonnay.jpg │ │ ├── jsbn.js │ │ ├── jsbn2.js │ │ └── sjcl.js │ ├── manifest.json │ └── service-worker.js ├── index.html ├── manifest.json ├── pages │ ├── auth │ │ ├── confirmRegistration.component.ts │ │ ├── confirmRegistration.html │ │ ├── forgotPassword.html │ │ ├── forgotPassword1.component.ts │ │ ├── forgotPassword2.component.ts │ │ ├── forgotPasswordStep2.html │ │ ├── login.component.ts │ │ ├── login.html │ │ ├── logout.component.ts │ │ ├── register.component.ts │ │ ├── register.html │ │ ├── resendCode.component.ts │ │ └── resendCode.html │ └── controlpanel │ │ ├── controlpanel.html │ │ ├── controlpanel.scss │ │ └── controlpanel.ts ├── providers │ ├── aws.service.ts │ ├── cognito.service.ts │ ├── events.service.ts │ ├── properties.service.ts │ ├── userLogin.service.ts │ ├── userParameters.service.ts │ └── userRegistration.service.ts ├── service-worker.js └── theme │ ├── global.scss │ └── variables.scss ├── tsconfig.json ├── tslint.json └── www └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | # Specifies intentionally untracked files to ignore when using Git 2 | # http://git-scm.com/docs/gitignore 3 | .editorconfig 4 | *~ 5 | *.sw[mnpcod] 6 | *.log 7 | *.tmp 8 | *.tmp.* 9 | log.txt 10 | *.sublime-project 11 | *.sublime-workspace 12 | .vscode/ 13 | npm-debug.log* 14 | 15 | .idea/ 16 | .sass-cache/ 17 | .tmp/ 18 | .versions/ 19 | coverage/ 20 | dist/ 21 | node_modules/ 22 | tmp/ 23 | temp/ 24 | hooks/ 25 | platforms/ 26 | plugins/ 27 | plugins/android.json 28 | plugins/ios.json 29 | www/ 30 | resources/ 31 | $RECYCLE.BIN/ 32 | 33 | .DS_Store 34 | Thumbs.db 35 | UserInterfaceState.xcuserstate 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## AWS Cognito with Ionic2 Quickstart 2 | 3 | ### Updates 4 | 10/14 -- Updated to Angular Final/Ionic RC0 5 | 6 | ### What does this app do? 7 | Quickly start using AWS Cognito and Ionic2 8 | 9 | ### Tech Stack 10 | #### Required Tools 11 | * [npm](https://www.npmjs.com/) 12 | 13 | #### Frameworks 14 | * [AWS JavaScript SDK](http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/browser-intro.html) 15 | * [Angular 2](https://angular.io/docs/ts/latest/quickstart.html) 16 | * [(Ionic)](http://ionicframework.com/docs/v2/getting-started/installation/) 17 | * [TypeScript](https://www.typescriptlang.org/docs/tutorial.html) 18 | 19 | ### Getting the code 20 | ``` 21 | # Clone it from github 22 | git clone --depth 1 git@github.com:vbudilov/aws-cognito-ionic2.git 23 | ``` 24 | ``` 25 | # Install the NPM and Bower packages 26 | npm install 27 | ``` 28 | ``` 29 | # Build & Run the app in dev mode 30 | ionic build; ionic serve 31 | ``` 32 | 33 | ### AWS Setup 34 | You will need to create the user pool manually through the console. 35 | 36 | ### Necessary changes 37 | By default, this app is using my user pool, which is defined in the ```app/services/properties.service.ts``` file. 38 | Update the file with the appropriate user pool info that you want to use 39 | -------------------------------------------------------------------------------- /config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | aws-congito-ionic2 4 | Vladimir Budilov 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /hooks/README.md: -------------------------------------------------------------------------------- 1 | 21 | # Cordova Hooks 22 | 23 | Cordova Hooks represent special scripts which could be added by application and plugin developers or even by your own build system to customize cordova commands. Hook scripts could be defined by adding them to the special predefined folder (`/hooks`) or via configuration files (`config.xml` and `plugin.xml`) and run serially in the following order: 24 | * Application hooks from `/hooks`; 25 | * Application hooks from `config.xml`; 26 | * Plugin hooks from `plugins/.../plugin.xml`. 27 | 28 | __Remember__: Make your scripts executable. 29 | 30 | __Note__: `.cordova/hooks` directory is also supported for backward compatibility, but we don't recommend using it as it is deprecated. 31 | 32 | ## Supported hook types 33 | The following hook types are supported: 34 | 35 | after_build/ 36 | after_compile/ 37 | after_docs/ 38 | after_emulate/ 39 | after_platform_add/ 40 | after_platform_rm/ 41 | after_platform_ls/ 42 | after_plugin_add/ 43 | after_plugin_ls/ 44 | after_plugin_rm/ 45 | after_plugin_search/ 46 | after_plugin_install/ <-- Plugin hooks defined in plugin.xml are executed exclusively for a plugin being installed 47 | after_prepare/ 48 | after_run/ 49 | after_serve/ 50 | before_build/ 51 | before_compile/ 52 | before_docs/ 53 | before_emulate/ 54 | before_platform_add/ 55 | before_platform_rm/ 56 | before_platform_ls/ 57 | before_plugin_add/ 58 | before_plugin_ls/ 59 | before_plugin_rm/ 60 | before_plugin_search/ 61 | before_plugin_install/ <-- Plugin hooks defined in plugin.xml are executed exclusively for a plugin being installed 62 | before_plugin_uninstall/ <-- Plugin hooks defined in plugin.xml are executed exclusively for a plugin being uninstalled 63 | before_prepare/ 64 | before_run/ 65 | before_serve/ 66 | pre_package/ <-- Windows 8 and Windows Phone only. 67 | 68 | ## Ways to define hooks 69 | ### Via '/hooks' directory 70 | To execute custom action when corresponding hook type is fired, use hook type as a name for a subfolder inside 'hooks' directory and place you script file here, for example: 71 | 72 | # script file will be automatically executed after each build 73 | hooks/after_build/after_build_custom_action.js 74 | 75 | 76 | ### Config.xml 77 | 78 | Hooks can be defined in project's `config.xml` using `` elements, for example: 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | ... 89 | 90 | 91 | 92 | 93 | 94 | 95 | ... 96 | 97 | 98 | ### Plugin hooks (plugin.xml) 99 | 100 | As a plugin developer you can define hook scripts using `` elements in a `plugin.xml` like that: 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | ... 109 | 110 | 111 | `before_plugin_install`, `after_plugin_install`, `before_plugin_uninstall` plugin hooks will be fired exclusively for the plugin being installed/uninstalled. 112 | 113 | ## Script Interface 114 | 115 | ### Javascript 116 | 117 | If you are writing hooks in Javascript you should use the following module definition: 118 | ```javascript 119 | module.exports = function(context) { 120 | ... 121 | } 122 | ``` 123 | 124 | You can make your scipts async using Q: 125 | ```javascript 126 | module.exports = function(context) { 127 | var Q = context.requireCordovaModule('q'); 128 | var deferral = new Q.defer(); 129 | 130 | setTimeout(function(){ 131 | console.log('hook.js>> end'); 132 | deferral.resolve(); 133 | }, 1000); 134 | 135 | return deferral.promise; 136 | } 137 | ``` 138 | 139 | `context` object contains hook type, executed script full path, hook options, command-line arguments passed to Cordova and top-level "cordova" object: 140 | ```json 141 | { 142 | "hook": "before_plugin_install", 143 | "scriptLocation": "c:\\script\\full\\path\\appBeforePluginInstall.js", 144 | "cmdLine": "The\\exact\\command\\cordova\\run\\with arguments", 145 | "opts": { 146 | "projectRoot":"C:\\path\\to\\the\\project", 147 | "cordova": { 148 | "platforms": ["wp8"], 149 | "plugins": ["com.plugin.withhooks"], 150 | "version": "0.21.7-dev" 151 | }, 152 | "plugin": { 153 | "id": "com.plugin.withhooks", 154 | "pluginInfo": { 155 | ... 156 | }, 157 | "platform": "wp8", 158 | "dir": "C:\\path\\to\\the\\project\\plugins\\com.plugin.withhooks" 159 | } 160 | }, 161 | "cordova": {...} 162 | } 163 | 164 | ``` 165 | `context.opts.plugin` object will only be passed to plugin hooks scripts. 166 | 167 | You can also require additional Cordova modules in your script using `context.requireCordovaModule` in the following way: 168 | ```javascript 169 | var Q = context.requireCordovaModule('q'); 170 | ``` 171 | 172 | __Note__: new module loader script interface is used for the `.js` files defined via `config.xml` or `plugin.xml` only. 173 | For compatibility reasons hook files specified via `/hooks` folders are run via Node child_process spawn, see 'Non-javascript' section below. 174 | 175 | ### Non-javascript 176 | 177 | Non-javascript scripts are run via Node child_process spawn from the project's root directory and have the root directory passes as the first argument. All other options are passed to the script using environment variables: 178 | 179 | * CORDOVA_VERSION - The version of the Cordova-CLI. 180 | * CORDOVA_PLATFORMS - Comma separated list of platforms that the command applies to (e.g.: android, ios). 181 | * CORDOVA_PLUGINS - Comma separated list of plugin IDs that the command applies to (e.g.: org.apache.cordova.file, org.apache.cordova.file-transfer) 182 | * CORDOVA_HOOK - Path to the hook that is being executed. 183 | * CORDOVA_CMDLINE - The exact command-line arguments passed to cordova (e.g.: cordova run ios --emulate) 184 | 185 | If a script returns a non-zero exit code, then the parent cordova command will be aborted. 186 | 187 | ## Writing hooks 188 | 189 | We highly recommend writing your hooks using Node.js so that they are 190 | cross-platform. Some good examples are shown here: 191 | 192 | [http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/](http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/) 193 | 194 | Also, note that even if you are working on Windows, and in case your hook scripts aren't bat files (which is recommended, if you want your scripts to work in non-Windows operating systems) Cordova CLI will expect a shebang line as the first line for it to know the interpreter it needs to use to launch the script. The shebang line should match the following example: 195 | 196 | #!/usr/bin/env [name_of_interpreter_executable] 197 | -------------------------------------------------------------------------------- /hooks/after_prepare/010_add_platform_class.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | // Add Platform Class 4 | // v1.0 5 | // Automatically adds the platform class to the body tag 6 | // after the `prepare` command. By placing the platform CSS classes 7 | // directly in the HTML built for the platform, it speeds up 8 | // rendering the correct layout/style for the specific platform 9 | // instead of waiting for the JS to figure out the correct classes. 10 | 11 | var fs = require('fs'); 12 | var path = require('path'); 13 | 14 | var rootdir = process.argv[2]; 15 | 16 | function addPlatformBodyTag(indexPath, platform) { 17 | // add the platform class to the body tag 18 | try { 19 | var platformClass = 'platform-' + platform; 20 | var cordovaClass = 'platform-cordova platform-webview'; 21 | 22 | var html = fs.readFileSync(indexPath, 'utf8'); 23 | 24 | var bodyTag = findBodyTag(html); 25 | if(!bodyTag) return; // no opening body tag, something's wrong 26 | 27 | if(bodyTag.indexOf(platformClass) > -1) return; // already added 28 | 29 | var newBodyTag = bodyTag; 30 | 31 | var classAttr = findClassAttr(bodyTag); 32 | if(classAttr) { 33 | // body tag has existing class attribute, add the classname 34 | var endingQuote = classAttr.substring(classAttr.length-1); 35 | var newClassAttr = classAttr.substring(0, classAttr.length-1); 36 | newClassAttr += ' ' + platformClass + ' ' + cordovaClass + endingQuote; 37 | newBodyTag = bodyTag.replace(classAttr, newClassAttr); 38 | 39 | } else { 40 | // add class attribute to the body tag 41 | newBodyTag = bodyTag.replace('>', ' class="' + platformClass + ' ' + cordovaClass + '">'); 42 | } 43 | 44 | html = html.replace(bodyTag, newBodyTag); 45 | 46 | fs.writeFileSync(indexPath, html, 'utf8'); 47 | 48 | process.stdout.write('add to body class: ' + platformClass + '\n'); 49 | } catch(e) { 50 | process.stdout.write(e); 51 | } 52 | } 53 | 54 | function findBodyTag(html) { 55 | // get the body tag 56 | try{ 57 | return html.match(/])(.*?)>/gi)[0]; 58 | }catch(e){} 59 | } 60 | 61 | function findClassAttr(bodyTag) { 62 | // get the body tag's class attribute 63 | try{ 64 | return bodyTag.match(/ class=["|'](.*?)["|']/gi)[0]; 65 | }catch(e){} 66 | } 67 | 68 | if (rootdir) { 69 | 70 | // go through each of the platform directories that have been prepared 71 | var platforms = (process.env.CORDOVA_PLATFORMS ? process.env.CORDOVA_PLATFORMS.split(',') : []); 72 | 73 | for(var x=0; x { 30 | this.awsUtil.initAwsService(); 31 | 32 | this.rootPage = this.loginPage; 33 | 34 | console.log("Hiding splash screen"); 35 | this.splash.hide(); 36 | this.listenToLoginEvents(); 37 | }); 38 | 39 | } 40 | 41 | openPage(page) { 42 | // Reset the nav controller to have just this page 43 | // we wouldn't want the back button to show in this scenario 44 | this.rootPage = page; 45 | 46 | // close the menu when clicking a link from the menu 47 | this.menu.close(); 48 | } 49 | 50 | listenToLoginEvents() { 51 | this.events.subscribe('user:login', () => { 52 | this.enableMenu(true); 53 | }); 54 | 55 | 56 | this.events.subscribe('user:logout', () => { 57 | this.enableMenu(false); 58 | }); 59 | } 60 | 61 | enableMenu(loggedIn) { 62 | this.menu.enable(loggedIn, 'loggedInMenu'); 63 | this.menu.enable(!loggedIn, 'loggedOutMenu'); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/app/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Pages 5 | 6 | 7 | 8 | 9 | Account 10 | 11 | 15 | 16 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | Pages 30 | 31 | 32 | 33 | 34 | Account 35 | 36 | 40 | 41 | 42 | 43 | 44 | 45 | Navigation 46 | 47 | 51 | 52 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from "@angular/core"; 2 | import {IonicApp, IonicModule} from "ionic-angular"; 3 | import {MyApp} from "./app.component"; 4 | import {CognitoUtil} from "../providers/cognito.service"; 5 | import {AwsUtil} from "../providers/aws.service"; 6 | import {ControlPanelComponent} from "../pages/controlpanel/controlpanel"; 7 | import {EventsService} from "../providers/events.service"; 8 | import {LoginComponent} from "../pages/auth/login.component"; 9 | import {RegisterComponent} from "../pages/auth/register.component"; 10 | import {ConfirmRegistrationComponent} from "../pages/auth/confirmRegistration.component"; 11 | import {ResendCodeComponent} from "../pages/auth/resendCode.component"; 12 | import {ForgotPasswordStep1Component} from "../pages/auth/forgotPassword1.component"; 13 | import {ForgotPasswordStep2Component} from "../pages/auth/forgotPassword2.component"; 14 | import {UserLoginService} from "../providers/userLogin.service"; 15 | import {UserParametersService} from "../providers/userParameters.service"; 16 | import {UserRegistrationService} from "../providers/userRegistration.service"; 17 | import {LogoutComponent} from "../pages/auth/logout.component"; 18 | import {BrowserModule} from "@angular/platform-browser"; 19 | 20 | 21 | @NgModule({ 22 | declarations: [ 23 | MyApp, 24 | LoginComponent, 25 | LogoutComponent, 26 | RegisterComponent, 27 | ConfirmRegistrationComponent, 28 | ResendCodeComponent, 29 | ForgotPasswordStep1Component, 30 | ForgotPasswordStep2Component, 31 | ControlPanelComponent 32 | ], 33 | imports: [ 34 | IonicModule.forRoot(MyApp), 35 | BrowserModule 36 | ], 37 | bootstrap: [IonicApp], 38 | entryComponents: [ 39 | MyApp, 40 | LoginComponent, 41 | LogoutComponent, 42 | RegisterComponent, 43 | ConfirmRegistrationComponent, 44 | ResendCodeComponent, 45 | ForgotPasswordStep1Component, 46 | ForgotPasswordStep2Component, 47 | ControlPanelComponent 48 | ], 49 | providers: [CognitoUtil, 50 | AwsUtil, 51 | UserLoginService, 52 | UserParametersService, 53 | UserRegistrationService, 54 | EventsService] 55 | }) 56 | 57 | export class AppModule { 58 | } 59 | -------------------------------------------------------------------------------- /src/app/main.ts: -------------------------------------------------------------------------------- 1 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 2 | import {AppModule} from "./app.module"; 3 | 4 | platformBrowserDynamic().bootstrapModule(AppModule); 5 | -------------------------------------------------------------------------------- /src/assets/icon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vbudilov/ionic-app-with-aws-cognito/669938b9e044e1df4d12583b7d23a06209abe22a/src/assets/icon/favicon.ico -------------------------------------------------------------------------------- /src/assets/js/amazon-cognito-identity.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright 2016 Amazon.com, 3 | * Inc. or its affiliates. All Rights Reserved. 4 | * 5 | * Licensed under the Amazon Software License (the "License"). 6 | * You may not use this file except in compliance with the 7 | * License. A copy of the License is located at 8 | * 9 | * http://aws.amazon.com/asl/ 10 | * 11 | * or in the "license" file accompanying this file. This file is 12 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 13 | * CONDITIONS OF ANY KIND, express or implied. See the License 14 | * for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | 19 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("sjcl"),require("aws-sdk/clients/cognitoidentityserviceprovider"),require("jsbn")):"function"==typeof define&&define.amd?define(["sjcl","aws-sdk/clients/cognitoidentityserviceprovider","jsbn"],t):"object"==typeof exports?exports.AmazonCognitoIdentity=t(require("sjcl"),require("aws-sdk/clients/cognitoidentityserviceprovider"),require("jsbn")):e.AmazonCognitoIdentity=t(e.sjcl,e.AWSCognito.CognitoIdentityServiceProvider,e)}(this,function(e,t,n){return function(e){function t(i){if(n[i])return n[i].exports;var s=n[i]={exports:{},id:i,loaded:!1};return e[i].call(s.exports,s,s.exports,t),s.loaded=!0,s.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){"use strict";function i(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t["default"]=e,t}function s(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var r=n(14);Object.keys(r).forEach(function(e){"default"!==e&&"__esModule"!==e&&Object.defineProperty(t,e,{enumerable:!0,get:function(){return r[e]}})});var o=n(10),a=s(o),u=i(r);Object.keys(u).forEach(function(e){a["default"][e]=u[e]})},function(t,n){t.exports=e},function(e,t,n){"use strict";function i(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t["default"]=e,t}function s(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n50}function c(b){return a.attributes[b]&&a.attributes[b].length>200}function d(a){return e.logger.error(a),null}var e=this,f=[];return f=Object.keys(a.metrics).filter(function(b){return"number"!=typeof a.metrics[b]}),"v2.0"!==a.version?d("Event must have version v2.0"):"string"!=typeof a.eventType?d("Event Type must be a string"):f.length>0?d("Event Metrics must be numeric ("+f[0]+")"):Object.keys(a.metrics).length+Object.keys(a.attributes).length>40?d("Event Metric and Attribute Count cannot exceed 40"):Object.keys(a.attributes).filter(b).length?d("Event Attribute names must be 1-50 characters"):Object.keys(a.metrics).filter(b).length?d("Event Metric names must be 1-50 characters"):Object.keys(a.attributes).filter(c).length?d("Event Attribute values cannot be longer than 200 characters"):a},a.prototype.createEvent=function(a,b,c,e){var f=this;this.logger.log("[Function:(AMA.Client).createEvent]"+(a?"\neventType:"+a:"")+(b?"\nsession:"+b:"")+(c?"\nattributes:"+JSON.stringify(c):"")+(e?"\nmetrics:"+JSON.stringify(e):"")),c=c||{},e=e||{},d.Util.mergeObjects(c,this.options.globalAttributes),d.Util.mergeObjects(e,this.options.globalMetrics),Object.keys(c).forEach(function(a){if("string"!=typeof c[a])try{c[a]=JSON.stringify(c[a])}catch(b){f.logger.warn("Error parsing attribute "+a)}});var g={eventType:a,timestamp:(new Date).toISOString(),session:{id:b.id,startTimestamp:b.startTimestamp},version:"v2.0",attributes:c,metrics:e};return b.stopTimestamp&&(g.session.stopTimestamp=b.stopTimestamp,g.session.duration=new Date(g.stopTimestamp).getTime()-new Date(g.startTimestamp).getTime()),this.validateEvent(g)},a.prototype.pushEvent=function(a){if(!a)return-1;this.logger.log("[Function:(AMA.Client).pushEvent]"+(a?"\nevent:"+JSON.stringify(a):""));var b=this.outputs.events.push(a);return this.storage.set(this.StorageKeys.EVENTS,this.outputs.events),b-1},a.prototype.recordEvent=function(a,b,c,e){this.logger.log("[Function:(AMA.Client).recordEvent]"+(a?"\neventType:"+a:"")+(b?"\nsession:"+b:"")+(c?"\nattributes:"+JSON.stringify(c):"")+(e?"\nmetrics:"+JSON.stringify(e):""));var f,g=this.createEvent(a,b,c,e);return g?(f=this.pushEvent(g),d.Util.getRequestBodySize(this.outputs.events)>=this.options.batchSizeLimit&&this.submitEvents(),this.outputs.events[f]):null},a.prototype.recordMonetizationEvent=function(a,b,c,d){return this.logger.log("[Function:(AMA.Client).recordMonetizationEvent]"+(a?"\nsession:"+a:"")+(b?"\nmonetizationDetails:"+JSON.stringify(b):"")+(c?"\nattributes:"+JSON.stringify(c):"")+(d?"\nmetrics:"+JSON.stringify(d):"")),c=c||{},d=d||{},c._currency=b.currency||c._currency,c._product_id=b.productId||c._product_id,d._quantity=b.quantity||d._quantity,"number"==typeof b.price?d._item_price=b.price||d._item_price:c._item_price_formatted=b.price||c._item_price_formatted,this.recordEvent("_monetization.purchase",a,c,d)},a.prototype.submitEvents=function(a){a=a||{},a.submitCallback=a.submitCallback||this.options.submitCallback,this.logger.log("[Function:(AMA.Client).submitEvents]"+(a?"\noptions:"+JSON.stringify(a):"")),this.options.autoSubmitEvents&&(clearTimeout(this.outputs.timeoutReference),this.outputs.timeoutReference=setTimeout(this.submitEvents.bind(this),this.options.autoSubmitInterval));var b;return this.outputs.isThrottled&&this.throttlingSuppressionFunction()0?b="Prevented submission while batches are in flight":0===this.outputs.batches.length&&0===this.outputs.events.length?b="No batches or events to be submitted":this.outputs.lastSubmitTimestamp&&d.Util.timestamp()-this.outputs.lastSubmitTimestamp<1e3&&(b="Prevented multiple submissions in under a second"),b?(this.logger.warn(b),[]):(this.generateBatches(),this.outputs.lastSubmitTimestamp=d.Util.timestamp(),this.outputs.isThrottled?(this.logger.warn("Is throttled submitting first batch"),a.batchId=this.outputs.batchIndex[0],[this.submitBatchById(a)]):this.submitAllBatches(a))},a.prototype.throttlingSuppressionFunction=function(a){return a=a||d.Util.timestamp(),Math.pow(a-this.outputs.lastSubmitTimestamp,2)/Math.pow(6e4,2)},a.prototype.generateBatches=function(){for(;this.outputs.events.length>0;){var a=this.outputs.events.length;for(this.logger.log(this.outputs.events.length+" events to be submitted");a>1&&d.Util.getRequestBodySize(this.outputs.events.slice(0,a))>this.options.batchSizeLimit;)this.logger.log("Finding Batch Size ("+this.options.batchSizeLimit+"): "+a+"("+d.Util.getRequestBodySize(this.outputs.events.slice(0,a))+")"),a-=1;this.persistBatch(this.outputs.events.slice(0,a))&&(this.outputs.events.splice(0,a),this.storage.set(this.StorageKeys.EVENTS,this.outputs.events))}},a.prototype.persistBatch=function(a){if(this.logger.log(a.length+" events in batch"),d.Util.getRequestBodySize(a)<512e3){var b=d.Util.GUID();return this.outputs.batches[b]=a,this.storage.set(this.StorageKeys.BATCHES,this.outputs.batches),this.outputs.batchIndex.push(b),this.storage.set(this.StorageKeys.BATCH_INDEX,this.outputs.batchIndex),!0}return this.logger.error("Events too large"),!1},a.prototype.submitAllBatches=function(a){a.submitCallback=a.submitCallback||this.options.submitCallback,this.logger.log("[Function:(AMA.Client).submitAllBatches]"+(a?"\noptions:"+JSON.stringify(a):""));var b=[],c=this;return this.outputs.batchIndex.forEach(function(d){a.batchId=d,a.clientContext=a.clientContext||c.options.clientContext,c.outputs.batchesInFlight[d]||b.push(c.submitBatchById(a))}),b},a.NON_RETRYABLE_EXCEPTIONS=["BadRequestException","SerializationException","ValidationException"],a.prototype.submitBatchById=function(a){if("object"!=typeof a||!a.batchId)return void this.logger.error("Invalid Options passed to submitBatchById");a.submitCallback=a.submitCallback||this.options.submitCallback,this.logger.log("[Function:(AMA.Client).submitBatchById]"+(a?"\noptions:"+JSON.stringify(a):""));var b={events:this.outputs.batches[a.batchId],clientContext:JSON.stringify(a.clientContext||this.options.clientContext)};return this.outputs.batchesInFlight[a.batchId]=d.Util.timestamp(),this.outputs.MobileAnalytics.putEvents(b,this.handlePutEventsResponse(a.batchId,a.submitCallback)),a.batchId},a.prototype.handlePutEventsResponse=function(b,c){var d=this;return function(e,f){var g=!0,h=d.outputs.isThrottled;e?(d.logger.error(e,f),(void 0===e.statusCode||400===e.statusCode)&&(a.NON_RETRYABLE_EXCEPTIONS.indexOf(e.code)<0&&(g=!1),d.outputs.isThrottled="ThrottlingException"===e.code,d.outputs.isThrottled&&d.logger.warn("Application is currently throttled"))):(d.logger.info("Events Submitted Successfully"),d.outputs.isThrottled=!1),g&&d.clearBatchById(b),delete d.outputs.batchesInFlight[b],c(e,f,b),h&&!d.outputs.isThrottled&&(d.logger.warn("Was throttled flushing remaining batches",c),d.submitAllBatches({submitCallback:c}))}},a.prototype.clearBatchById=function(a){this.logger.log("[Function:(AMA.Client).clearBatchById]"+(a?"\nbatchId:"+a:"")),-1!==this.outputs.batchIndex.indexOf(a)&&(delete this.outputs.batches[a],this.outputs.batchIndex.splice(this.outputs.batchIndex.indexOf(a),1),this.storage.set(this.StorageKeys.BATCH_INDEX,this.outputs.batchIndex),this.storage.set(this.StorageKeys.BATCHES,this.outputs.batches))},a}(),b.exports=d.Client}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./MobileAnalyticsUtilities.js":4,"./StorageClients/LocalStorage.js":5,"./StorageClients/StorageKeys.js":6}],2:[function(a,b){(function(c){var d=c.AMA;d.Storage=a("./StorageClients/LocalStorage.js"),d.StorageKeys=a("./StorageClients/StorageKeys.js"),d.Util=a("./MobileAnalyticsUtilities.js"),d.Session=function(){"use strict";var a=function(a){this.options=a||{},this.options.logger=this.options.logger||{},this.logger={log:this.options.logger.log||d.Util.NOP,info:this.options.logger.info||d.Util.NOP,warn:this.options.logger.warn||d.Util.NOP,error:this.options.logger.error||d.Util.NOP},this.logger.log=this.logger.log.bind(this.options.logger),this.logger.info=this.logger.info.bind(this.options.logger),this.logger.warn=this.logger.warn.bind(this.options.logger),this.logger.error=this.logger.error.bind(this.options.logger),this.logger.log("[Function:(AWS.MobileAnalyticsClient)Session Constructor]"+(a?"\noptions:"+JSON.stringify(a):"")),this.options.expirationCallback=this.options.expirationCallback||d.Util.NOP,this.id=this.options.sessionId||d.Util.GUID(),this.sessionLength=this.options.sessionLength||6e5,this.StorageKeys={SESSION_ID:d.StorageKeys.SESSION_ID+this.id,SESSION_EXPIRATION:d.StorageKeys.SESSION_EXPIRATION+this.id,SESSION_START_TIMESTAMP:d.StorageKeys.SESSION_START_TIMESTAMP+this.id},this.startTimestamp=this.options.startTime||this.options.storage.get(this.StorageKeys.SESSION_START_TIMESTAMP)||(new Date).toISOString(),this.expirationDate=parseInt(this.options.storage.get(this.StorageKeys.SESSION_EXPIRATION),10),isNaN(this.expirationDate)&&(this.expirationDate=(new Date).getTime()+this.sessionLength),this.options.storage.set(this.StorageKeys.SESSION_ID,this.id),this.options.storage.set(this.StorageKeys.SESSION_EXPIRATION,this.expirationDate),this.options.storage.set(this.StorageKeys.SESSION_START_TIMESTAMP,this.startTimestamp),this.sessionTimeoutReference=setTimeout(this.expireSession.bind(this),this.sessionLength)};return a.prototype.expireSession=function(a){this.logger.log("[Function:(Session).expireSession]"),a=a||this.options.expirationCallback;var b=a(this);"boolean"==typeof b&&b&&(b=this.options.sessionLength),"number"==typeof b?this.extendSession(b):this.clearSession()},a.prototype.clearSession=function(){this.logger.log("[Function:(Session).clearSession]"),clearTimeout(this.sessionTimeoutReference),this.options.storage.delete(this.StorageKeys.SESSION_ID),this.options.storage.delete(this.StorageKeys.SESSION_EXPIRATION),this.options.storage.delete(this.StorageKeys.SESSION_START_TIMESTAMP)},a.prototype.extendSession=function(a){this.logger.log("[Function:(Session).extendSession]"+(a?"\nsessionExtensionLength:"+a:"")),a=a||this.sessionLength,this.setSessionTimeout(this.expirationDate+parseInt(a,10))},a.prototype.stopSession=function(a){this.logger.log("[Function:(Session).stopSession]"+(a?"\nstopDate:"+a:"")),this.stopTimestamp=a||(new Date).toISOString()},a.prototype.resetSessionTimeout=function(a){this.logger.log("[Function:(Session).resetSessionTimeout]"+(a?"\nmilliseconds:"+a:"")),a=a||this.sessionLength,this.setSessionTimeout((new Date).getTime()+a)},a.prototype.setSessionTimeout=function(a){this.logger.log("[Function:(Session).setSessionTimeout]"+(a?"\ntimeout:"+a:"")),clearTimeout(this.sessionTimeoutReference),this.expirationDate=a,this.options.storage.set(this.StorageKeys.SESSION_EXPIRATION,this.expirationDate),this.sessionTimeoutReference=setTimeout(this.expireSession.bind(this),this.expirationDate-(new Date).getTime())},a}(),b.exports=d.Session}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./MobileAnalyticsUtilities.js":4,"./StorageClients/LocalStorage.js":5,"./StorageClients/StorageKeys.js":6}],3:[function(a,b){(function(c){var d=c.AMA;d.Storage=a("./StorageClients/LocalStorage.js"),d.StorageKeys=a("./StorageClients/StorageKeys.js"),d.Session=a("./MobileAnalyticsSession.js"),d.Client=a("./MobileAnalyticsClient.js"),d.Manager=function(){"use strict";var a=function(a){function b(a){a.client.storage.each(function(b){0===b.indexOf(d.StorageKeys.SESSION_ID)&&(a.outputs.session=new d.Session({storage:a.client.storage,sessionId:a.client.storage.get(b),sessionLength:a.options.sessionLength,expirationCallback:function(b){var c=a.options.expirationCallback(b);return c===!0||"number"==typeof c?c:void a.stopSession()}}),(new Date).getTime()>a.outputs.session.expirationDate&&(a.outputs.session.expireSession(),delete a.outputs.session))})}a instanceof d.Client?this.client=a:(a._autoSubmitEvents=a.autoSubmitEvents,a.autoSubmitEvents=!1,this.client=new d.Client(a),a.autoSubmitEvents=a._autoSubmitEvents!==!1,delete a._autoSubmitEvents),this.options=this.client.options,this.outputs=this.client.outputs,this.options.expirationCallback=this.options.expirationCallback||d.Util.NOP,b(this),this.outputs.session||this.startSession(),this.options.autoSubmitEvents&&this.client.submitEvents()};return a.prototype.submitEvents=function(a){return this.client.submitEvents(a)},a.prototype.startSession=function(){return this.client.logger.log("[Function:(AMA.Manager).startSession]"),this.outputs.session&&this.outputs.session.clearSession(),this.outputs.session=new d.Session({storage:this.client.storage,logger:this.client.options.logger,sessionLength:this.options.sessionLength,expirationCallback:function(a){var b=this.options.expirationCallback(a);return b===!0||"number"==typeof b?b:void this.stopSession()}.bind(this)}),this.recordEvent("_session.start")},a.prototype.extendSession=function(a){return this.outputs.session.extendSession(a||this.options.sessionLength)},a.prototype.stopSession=function(){return this.client.logger.log("[Function:(AMA.Manager).stopSession]"),this.outputs.session.stopSession(),this.outputs.session.expireSession(d.Util.NOP),this.recordEvent("_session.stop")},a.prototype.renewSession=function(){return this.stopSession(),this.startSession(),this.outputs.session},a.prototype.createEvent=function(a,b,c){return this.client.createEvent(a,this.outputs.session,b,c)},a.prototype.recordEvent=function(a,b,c){return this.client.recordEvent(a,this.outputs.session,b,c)},a.prototype.recordMonetizationEvent=function(a,b,c){return this.client.recordMonetizationEvent(this.outputs.session,a,b,c)},a}(),b.exports=d.Manager}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./MobileAnalyticsClient.js":1,"./MobileAnalyticsSession.js":2,"./StorageClients/LocalStorage.js":5,"./StorageClients/StorageKeys.js":6}],4:[function(a,b){(function(a){var c=a.AMA;c.Util=function(){"use strict";function a(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)}function b(a){"string"!=typeof a&&(a=JSON.stringify(a));var b,c,d=a.length;for(b=a.length-1;b>=0;b-=1)c=a.charCodeAt(b),c>127&&2047>=c?d+=1:c>2047&&65535>=c&&(d+=2),c>=56320&&57343>=c&&(b-=1);return d}function c(){return a()+a()+"-"+a()+"-"+a()+"-"+a()+"-"+a()+a()+a()}function d(a,b){return Object.keys(b).forEach(function(c){b.hasOwnProperty(c)&&(a[c]=a[c]||b[c])}),a}function e(a,b){return d(JSON.parse(JSON.stringify(a)),b||{})}function f(){return void 0}function g(){return(new Date).getTime()}return{copy:e,GUID:c,getRequestBodySize:b,mergeObjects:d,NOP:f,timestamp:g}}(),b.exports=c.Util}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],5:[function(a,b){(function(c){var d=c.AMA;d.Util=a("../MobileAnalyticsUtilities.js"),d.Storage=function(){"use strict";var a=function(a){this.storageKey="AWSMobileAnalyticsStorage-"+a,c[this.storageKey]=c[this.storageKey]||{},this.cache=c[this.storageKey],this.cache.id=this.cache.id||d.Util.GUID(),this.logger={log:d.Util.NOP,info:d.Util.NOP,warn:d.Util.NOP,error:d.Util.NOP},this.reload()};if("object"==typeof localStorage&&"object"===Storage)try{localStorage.setItem("TestLocalStorage",1),localStorage.removeItem("TestLocalStorage")}catch(b){Storage.prototype._setItem=Storage.prototype.setItem,Storage.prototype.setItem=d.Util.NOP,console.warn('Your web browser does not support storing settings locally. In Safari, the most common cause of this is using "Private Browsing Mode". Some settings may not save or some features may not work properly for you.')}return a.prototype.type="LOCAL_STORAGE",a.prototype.get=function(a){return this.cache[a]},a.prototype.set=function(a,b){return this.cache[a]=b,this.saveToLocalStorage()},a.prototype.delete=function(a){delete this.cache[a],this.saveToLocalStorage()},a.prototype.each=function(a){var b;for(b in this.cache)this.cache.hasOwnProperty(b)&&a(b,this.cache[b])},a.prototype.saveToLocalStorage=function(){if(this.supportsLocalStorage())try{this.logger.log("[Function:(AWS.MobileAnalyticsClient.Storage).saveToLocalStorage]"),window.localStorage.setItem(this.storageKey,JSON.stringify(this.cache)),this.logger.log("LocalStorage Cache: "+JSON.stringify(this.cache))}catch(a){this.logger.log("Error saving to LocalStorage: "+JSON.stringify(a))}else this.logger.log("LocalStorage is not available")},a.prototype.reload=function(){if(this.supportsLocalStorage()){var a;try{if(this.logger.log("[Function:(AWS.MobileAnalyticsClient.Storage).loadLocalStorage]"),a=window.localStorage.getItem(this.storageKey),this.logger.log("LocalStorage Cache: "+a),a)try{this.cache=JSON.parse(a)}catch(b){this.clearLocalStorage()}}catch(c){this.logger.log("Error loading LocalStorage: "+JSON.stringify(c)),this.clearLocalStorage()}}else this.logger.log("LocalStorage is not available")},a.prototype.setLogger=function(a){this.logger=a},a.prototype.supportsLocalStorage=function(){try{return window&&window.localStorage}catch(a){return!1}},a.prototype.clearLocalStorage=function(){if(this.cache={},this.supportsLocalStorage())try{this.logger.log("[Function:(AWS.MobileAnalyticsClient.Storage).clearLocalStorage]"),window.localStorage.removeItem(this.storageKey),c[this.storageKey]={}}catch(a){this.logger.log("Error clearing LocalStorage: "+JSON.stringify(a))}else this.logger.log("LocalStorage is not available")},a}(),b.exports=d.Storage}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"../MobileAnalyticsUtilities.js":4}],6:[function(a,b){(function(a){var c=a.AMA;c.StorageKeys={CLIENT_ID:"AWSMobileAnalyticsClientId",GLOBAL_ATTRIBUTES:"AWSMobileAnalyticsGlobalAttributes",GLOBAL_METRICS:"AWSMobileAnalyticsGlobalMetrics",SESSION_ID:"MobileAnalyticsSessionId",SESSION_EXPIRATION:"MobileAnalyticsSessionExpiration",SESSION_START_TIMESTAMP:"MobileAnalyticsSessionStartTimeStamp"},b.exports=c.StorageKeys}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],7:[function(a,b){(function(c){c.AMA=c.AMA||{},a("./MobileAnalyticsClient.js"),a("./MobileAnalyticsUtilities.js"),a("./StorageClients/StorageKeys.js"),a("./StorageClients/LocalStorage.js"),a("./MobileAnalyticsSession.js"),a("./MobileAnalyticsSessionManager.js"),b.exports=c.AMA}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./MobileAnalyticsClient.js":1,"./MobileAnalyticsSession.js":2,"./MobileAnalyticsSessionManager.js":3,"./MobileAnalyticsUtilities.js":4,"./StorageClients/LocalStorage.js":5,"./StorageClients/StorageKeys.js":6}]},{},[7]); -------------------------------------------------------------------------------- /src/assets/js/chardonnay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vbudilov/ionic-app-with-aws-cognito/669938b9e044e1df4d12583b7d23a06209abe22a/src/assets/js/chardonnay.jpg -------------------------------------------------------------------------------- /src/assets/js/jsbn.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2005 Tom Wu 2 | // All Rights Reserved. 3 | // See "LICENSE" for details. 4 | 5 | // Basic JavaScript BN library - subset useful for RSA encryption. 6 | 7 | // Bits per digit 8 | var dbits; 9 | 10 | // JavaScript engine analysis 11 | var canary = 0xdeadbeefcafe; 12 | var j_lm = ((canary & 0xffffff) == 0xefcafe); 13 | 14 | // (public) Constructor 15 | function BigInteger(a, b, c) { 16 | if (a != null) 17 | if ("number" == typeof a) this.fromNumber(a, b, c); 18 | else if (b == null && "string" != typeof a) this.fromString(a, 256); 19 | else this.fromString(a, b); 20 | } 21 | 22 | // return new, unset BigInteger 23 | function nbi() { 24 | return new BigInteger(null); 25 | } 26 | 27 | // am: Compute w_j += (x*this_i), propagate carries, 28 | // c is initial carry, returns final carry. 29 | // c < 3*dvalue, x < 2*dvalue, this_i < dvalue 30 | // We need to select the fastest one that works in this environment. 31 | 32 | // am1: use a single mult and divide to get the high bits, 33 | // max digit bits should be 26 because 34 | // max internal value = 2*dvalue^2-2*dvalue (< 2^53) 35 | function am1(i, x, w, j, c, n) { 36 | while (--n >= 0) { 37 | var v = x * this[i++] + w[j] + c; 38 | c = Math.floor(v / 0x4000000); 39 | w[j++] = v & 0x3ffffff; 40 | } 41 | return c; 42 | } 43 | // am2 avoids a big mult-and-extract completely. 44 | // Max digit bits should be <= 30 because we do bitwise ops 45 | // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) 46 | function am2(i, x, w, j, c, n) { 47 | var xl = x & 0x7fff, xh = x >> 15; 48 | while (--n >= 0) { 49 | var l = this[i] & 0x7fff; 50 | var h = this[i++] >> 15; 51 | var m = xh * l + h * xl; 52 | l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff); 53 | c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30); 54 | w[j++] = l & 0x3fffffff; 55 | } 56 | return c; 57 | } 58 | // Alternately, set max digit bits to 28 since some 59 | // browsers slow down when dealing with 32-bit numbers. 60 | function am3(i, x, w, j, c, n) { 61 | var xl = x & 0x3fff, xh = x >> 14; 62 | while (--n >= 0) { 63 | var l = this[i] & 0x3fff; 64 | var h = this[i++] >> 14; 65 | var m = xh * l + h * xl; 66 | l = xl * l + ((m & 0x3fff) << 14) + w[j] + c; 67 | c = (l >> 28) + (m >> 14) + xh * h; 68 | w[j++] = l & 0xfffffff; 69 | } 70 | return c; 71 | } 72 | if (j_lm && (navigator.appName == "Microsoft Internet Explorer")) { 73 | BigInteger.prototype.am = am2; 74 | dbits = 30; 75 | } 76 | else if (j_lm && (navigator.appName != "Netscape")) { 77 | BigInteger.prototype.am = am1; 78 | dbits = 26; 79 | } 80 | else { // Mozilla/Netscape seems to prefer am3 81 | BigInteger.prototype.am = am3; 82 | dbits = 28; 83 | } 84 | 85 | BigInteger.prototype.DB = dbits; 86 | BigInteger.prototype.DM = ((1 << dbits) - 1); 87 | BigInteger.prototype.DV = (1 << dbits); 88 | 89 | var BI_FP = 52; 90 | BigInteger.prototype.FV = Math.pow(2, BI_FP); 91 | BigInteger.prototype.F1 = BI_FP - dbits; 92 | BigInteger.prototype.F2 = 2 * dbits - BI_FP; 93 | 94 | // Digit conversions 95 | var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz"; 96 | var BI_RC = new Array(); 97 | var rr, vv; 98 | rr = "0".charCodeAt(0); 99 | for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv; 100 | rr = "a".charCodeAt(0); 101 | for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; 102 | rr = "A".charCodeAt(0); 103 | for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; 104 | 105 | function int2char(n) { 106 | return BI_RM.charAt(n); 107 | } 108 | function intAt(s, i) { 109 | var c = BI_RC[s.charCodeAt(i)]; 110 | return (c == null) ? -1 : c; 111 | } 112 | 113 | // (protected) copy this to r 114 | function bnpCopyTo(r) { 115 | for (var i = this.t - 1; i >= 0; --i) r[i] = this[i]; 116 | r.t = this.t; 117 | r.s = this.s; 118 | } 119 | 120 | // (protected) set from integer value x, -DV <= x < DV 121 | function bnpFromInt(x) { 122 | this.t = 1; 123 | this.s = (x < 0) ? -1 : 0; 124 | if (x > 0) this[0] = x; 125 | else if (x < -1) this[0] = x + this.DV; 126 | else this.t = 0; 127 | } 128 | 129 | // return bigint initialized to value 130 | function nbv(i) { 131 | var r = nbi(); 132 | r.fromInt(i); 133 | return r; 134 | } 135 | 136 | // (protected) set from string and radix 137 | function bnpFromString(s, b) { 138 | var k; 139 | if (b == 16) k = 4; 140 | else if (b == 8) k = 3; 141 | else if (b == 256) k = 8; // byte array 142 | else if (b == 2) k = 1; 143 | else if (b == 32) k = 5; 144 | else if (b == 4) k = 2; 145 | else { 146 | this.fromRadix(s, b); 147 | return; 148 | } 149 | this.t = 0; 150 | this.s = 0; 151 | var i = s.length, mi = false, sh = 0; 152 | while (--i >= 0) { 153 | var x = (k == 8) ? s[i] & 0xff : intAt(s, i); 154 | if (x < 0) { 155 | if (s.charAt(i) == "-") mi = true; 156 | continue; 157 | } 158 | mi = false; 159 | if (sh == 0) 160 | this[this.t++] = x; 161 | else if (sh + k > this.DB) { 162 | this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh; 163 | this[this.t++] = (x >> (this.DB - sh)); 164 | } 165 | else 166 | this[this.t - 1] |= x << sh; 167 | sh += k; 168 | if (sh >= this.DB) sh -= this.DB; 169 | } 170 | if (k == 8 && (s[0] & 0x80) != 0) { 171 | this.s = -1; 172 | if (sh > 0) this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh; 173 | } 174 | this.clamp(); 175 | if (mi) BigInteger.ZERO.subTo(this, this); 176 | } 177 | 178 | // (protected) clamp off excess high words 179 | function bnpClamp() { 180 | var c = this.s & this.DM; 181 | while (this.t > 0 && this[this.t - 1] == c) --this.t; 182 | } 183 | 184 | // (public) return string representation in given radix 185 | function bnToString(b) { 186 | if (this.s < 0) return "-" + this.negate().toString(b); 187 | var k; 188 | if (b == 16) k = 4; 189 | else if (b == 8) k = 3; 190 | else if (b == 2) k = 1; 191 | else if (b == 32) k = 5; 192 | else if (b == 4) k = 2; 193 | else return this.toRadix(b); 194 | var km = (1 << k) - 1, d, m = false, r = "", i = this.t; 195 | var p = this.DB - (i * this.DB) % k; 196 | if (i-- > 0) { 197 | if (p < this.DB && (d = this[i] >> p) > 0) { 198 | m = true; 199 | r = int2char(d); 200 | } 201 | while (i >= 0) { 202 | if (p < k) { 203 | d = (this[i] & ((1 << p) - 1)) << (k - p); 204 | d |= this[--i] >> (p += this.DB - k); 205 | } 206 | else { 207 | d = (this[i] >> (p -= k)) & km; 208 | if (p <= 0) { 209 | p += this.DB; 210 | --i; 211 | } 212 | } 213 | if (d > 0) m = true; 214 | if (m) r += int2char(d); 215 | } 216 | } 217 | return m ? r : "0"; 218 | } 219 | 220 | // (public) -this 221 | function bnNegate() { 222 | var r = nbi(); 223 | BigInteger.ZERO.subTo(this, r); 224 | return r; 225 | } 226 | 227 | // (public) |this| 228 | function bnAbs() { 229 | return (this.s < 0) ? this.negate() : this; 230 | } 231 | 232 | // (public) return + if this > a, - if this < a, 0 if equal 233 | function bnCompareTo(a) { 234 | var r = this.s - a.s; 235 | if (r != 0) return r; 236 | var i = this.t; 237 | r = i - a.t; 238 | if (r != 0) return (this.s < 0) ? -r : r; 239 | while (--i >= 0) if ((r = this[i] - a[i]) != 0) return r; 240 | return 0; 241 | } 242 | 243 | // returns bit length of the integer x 244 | function nbits(x) { 245 | var r = 1, t; 246 | if ((t = x >>> 16) != 0) { 247 | x = t; 248 | r += 16; 249 | } 250 | if ((t = x >> 8) != 0) { 251 | x = t; 252 | r += 8; 253 | } 254 | if ((t = x >> 4) != 0) { 255 | x = t; 256 | r += 4; 257 | } 258 | if ((t = x >> 2) != 0) { 259 | x = t; 260 | r += 2; 261 | } 262 | if ((t = x >> 1) != 0) { 263 | x = t; 264 | r += 1; 265 | } 266 | return r; 267 | } 268 | 269 | // (public) return the number of bits in "this" 270 | function bnBitLength() { 271 | if (this.t <= 0) return 0; 272 | return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM)); 273 | } 274 | 275 | // (protected) r = this << n*DB 276 | function bnpDLShiftTo(n, r) { 277 | var i; 278 | for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i]; 279 | for (i = n - 1; i >= 0; --i) r[i] = 0; 280 | r.t = this.t + n; 281 | r.s = this.s; 282 | } 283 | 284 | // (protected) r = this >> n*DB 285 | function bnpDRShiftTo(n, r) { 286 | for (var i = n; i < this.t; ++i) r[i - n] = this[i]; 287 | r.t = Math.max(this.t - n, 0); 288 | r.s = this.s; 289 | } 290 | 291 | // (protected) r = this << n 292 | function bnpLShiftTo(n, r) { 293 | var bs = n % this.DB; 294 | var cbs = this.DB - bs; 295 | var bm = (1 << cbs) - 1; 296 | var ds = Math.floor(n / this.DB), c = (this.s << bs) & this.DM, i; 297 | for (i = this.t - 1; i >= 0; --i) { 298 | r[i + ds + 1] = (this[i] >> cbs) | c; 299 | c = (this[i] & bm) << bs; 300 | } 301 | for (i = ds - 1; i >= 0; --i) r[i] = 0; 302 | r[ds] = c; 303 | r.t = this.t + ds + 1; 304 | r.s = this.s; 305 | r.clamp(); 306 | } 307 | 308 | // (protected) r = this >> n 309 | function bnpRShiftTo(n, r) { 310 | r.s = this.s; 311 | var ds = Math.floor(n / this.DB); 312 | if (ds >= this.t) { 313 | r.t = 0; 314 | return; 315 | } 316 | var bs = n % this.DB; 317 | var cbs = this.DB - bs; 318 | var bm = (1 << bs) - 1; 319 | r[0] = this[ds] >> bs; 320 | for (var i = ds + 1; i < this.t; ++i) { 321 | r[i - ds - 1] |= (this[i] & bm) << cbs; 322 | r[i - ds] = this[i] >> bs; 323 | } 324 | if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs; 325 | r.t = this.t - ds; 326 | r.clamp(); 327 | } 328 | 329 | // (protected) r = this - a 330 | function bnpSubTo(a, r) { 331 | var i = 0, c = 0, m = Math.min(a.t, this.t); 332 | while (i < m) { 333 | c += this[i] - a[i]; 334 | r[i++] = c & this.DM; 335 | c >>= this.DB; 336 | } 337 | if (a.t < this.t) { 338 | c -= a.s; 339 | while (i < this.t) { 340 | c += this[i]; 341 | r[i++] = c & this.DM; 342 | c >>= this.DB; 343 | } 344 | c += this.s; 345 | } 346 | else { 347 | c += this.s; 348 | while (i < a.t) { 349 | c -= a[i]; 350 | r[i++] = c & this.DM; 351 | c >>= this.DB; 352 | } 353 | c -= a.s; 354 | } 355 | r.s = (c < 0) ? -1 : 0; 356 | if (c < -1) r[i++] = this.DV + c; 357 | else if (c > 0) r[i++] = c; 358 | r.t = i; 359 | r.clamp(); 360 | } 361 | 362 | // (protected) r = this * a, r != this,a (HAC 14.12) 363 | // "this" should be the larger one if appropriate. 364 | function bnpMultiplyTo(a, r) { 365 | var x = this.abs(), y = a.abs(); 366 | var i = x.t; 367 | r.t = i + y.t; 368 | while (--i >= 0) r[i] = 0; 369 | for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t); 370 | r.s = 0; 371 | r.clamp(); 372 | if (this.s != a.s) BigInteger.ZERO.subTo(r, r); 373 | } 374 | 375 | // (protected) r = this^2, r != this (HAC 14.16) 376 | function bnpSquareTo(r) { 377 | var x = this.abs(); 378 | var i = r.t = 2 * x.t; 379 | while (--i >= 0) r[i] = 0; 380 | for (i = 0; i < x.t - 1; ++i) { 381 | var c = x.am(i, x[i], r, 2 * i, 0, 1); 382 | if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) { 383 | r[i + x.t] -= x.DV; 384 | r[i + x.t + 1] = 1; 385 | } 386 | } 387 | if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1); 388 | r.s = 0; 389 | r.clamp(); 390 | } 391 | 392 | // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) 393 | // r != q, this != m. q or r may be null. 394 | function bnpDivRemTo(m, q, r) { 395 | var pm = m.abs(); 396 | if (pm.t <= 0) return; 397 | var pt = this.abs(); 398 | if (pt.t < pm.t) { 399 | if (q != null) q.fromInt(0); 400 | if (r != null) this.copyTo(r); 401 | return; 402 | } 403 | if (r == null) r = nbi(); 404 | var y = nbi(), ts = this.s, ms = m.s; 405 | var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus 406 | if (nsh > 0) { 407 | pm.lShiftTo(nsh, y); 408 | pt.lShiftTo(nsh, r); 409 | } 410 | else { 411 | pm.copyTo(y); 412 | pt.copyTo(r); 413 | } 414 | var ys = y.t; 415 | var y0 = y[ys - 1]; 416 | if (y0 == 0) return; 417 | var yt = y0 * (1 << this.F1) + ((ys > 1) ? y[ys - 2] >> this.F2 : 0); 418 | var d1 = this.FV / yt, d2 = (1 << this.F1) / yt, e = 1 << this.F2; 419 | var i = r.t, j = i - ys, t = (q == null) ? nbi() : q; 420 | y.dlShiftTo(j, t); 421 | if (r.compareTo(t) >= 0) { 422 | r[r.t++] = 1; 423 | r.subTo(t, r); 424 | } 425 | BigInteger.ONE.dlShiftTo(ys, t); 426 | t.subTo(y, y); // "negative" y so we can replace sub with am later 427 | while (y.t < ys) y[y.t++] = 0; 428 | while (--j >= 0) { 429 | // Estimate quotient digit 430 | var qd = (r[--i] == y0) ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2); 431 | if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { // Try it out 432 | y.dlShiftTo(j, t); 433 | r.subTo(t, r); 434 | while (r[i] < --qd) r.subTo(t, r); 435 | } 436 | } 437 | if (q != null) { 438 | r.drShiftTo(ys, q); 439 | if (ts != ms) BigInteger.ZERO.subTo(q, q); 440 | } 441 | r.t = ys; 442 | r.clamp(); 443 | if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder 444 | if (ts < 0) BigInteger.ZERO.subTo(r, r); 445 | } 446 | 447 | // (public) this mod a 448 | function bnMod(a) { 449 | var r = nbi(); 450 | this.abs().divRemTo(a, null, r); 451 | if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r); 452 | return r; 453 | } 454 | 455 | // Modular reduction using "classic" algorithm 456 | function Classic(m) { 457 | this.m = m; 458 | } 459 | function cConvert(x) { 460 | if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); 461 | else return x; 462 | } 463 | function cRevert(x) { 464 | return x; 465 | } 466 | function cReduce(x) { 467 | x.divRemTo(this.m, null, x); 468 | } 469 | function cMulTo(x, y, r) { 470 | x.multiplyTo(y, r); 471 | this.reduce(r); 472 | } 473 | function cSqrTo(x, r) { 474 | x.squareTo(r); 475 | this.reduce(r); 476 | } 477 | 478 | Classic.prototype.convert = cConvert; 479 | Classic.prototype.revert = cRevert; 480 | Classic.prototype.reduce = cReduce; 481 | Classic.prototype.mulTo = cMulTo; 482 | Classic.prototype.sqrTo = cSqrTo; 483 | 484 | // (protected) return "-1/this % 2^DB"; useful for Mont. reduction 485 | // justification: 486 | // xy == 1 (mod m) 487 | // xy = 1+km 488 | // xy(2-xy) = (1+km)(1-km) 489 | // x[y(2-xy)] = 1-k^2m^2 490 | // x[y(2-xy)] == 1 (mod m^2) 491 | // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 492 | // should reduce x and y(2-xy) by m^2 at each step to keep size bounded. 493 | // JS multiply "overflows" differently from C/C++, so care is needed here. 494 | function bnpInvDigit() { 495 | if (this.t < 1) return 0; 496 | var x = this[0]; 497 | if ((x & 1) == 0) return 0; 498 | var y = x & 3; // y == 1/x mod 2^2 499 | y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4 500 | y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8 501 | y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 502 | // last step - calculate inverse mod DV directly; 503 | // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints 504 | y = (y * (2 - x * y % this.DV)) % this.DV; // y == 1/x mod 2^dbits 505 | // we really want the negative inverse, and -DV < y < DV 506 | return (y > 0) ? this.DV - y : -y; 507 | } 508 | 509 | // Montgomery reduction 510 | function Montgomery(m) { 511 | this.m = m; 512 | this.mp = m.invDigit(); 513 | this.mpl = this.mp & 0x7fff; 514 | this.mph = this.mp >> 15; 515 | this.um = (1 << (m.DB - 15)) - 1; 516 | this.mt2 = 2 * m.t; 517 | } 518 | 519 | // xR mod m 520 | function montConvert(x) { 521 | var r = nbi(); 522 | x.abs().dlShiftTo(this.m.t, r); 523 | r.divRemTo(this.m, null, r); 524 | if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r); 525 | return r; 526 | } 527 | 528 | // x/R mod m 529 | function montRevert(x) { 530 | var r = nbi(); 531 | x.copyTo(r); 532 | this.reduce(r); 533 | return r; 534 | } 535 | 536 | // x = x/R mod m (HAC 14.32) 537 | function montReduce(x) { 538 | while (x.t <= this.mt2) // pad x so am has enough room later 539 | x[x.t++] = 0; 540 | for (var i = 0; i < this.m.t; ++i) { 541 | // faster way of calculating u0 = x[i]*mp mod DV 542 | var j = x[i] & 0x7fff; 543 | var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM; 544 | // use am to combine the multiply-shift-add into one call 545 | j = i + this.m.t; 546 | x[j] += this.m.am(0, u0, x, i, 0, this.m.t); 547 | // propagate carry 548 | while (x[j] >= x.DV) { 549 | x[j] -= x.DV; 550 | x[++j]++; 551 | } 552 | } 553 | x.clamp(); 554 | x.drShiftTo(this.m.t, x); 555 | if (x.compareTo(this.m) >= 0) x.subTo(this.m, x); 556 | } 557 | 558 | // r = "x^2/R mod m"; x != r 559 | function montSqrTo(x, r) { 560 | x.squareTo(r); 561 | this.reduce(r); 562 | } 563 | 564 | // r = "xy/R mod m"; x,y != r 565 | function montMulTo(x, y, r) { 566 | x.multiplyTo(y, r); 567 | this.reduce(r); 568 | } 569 | 570 | Montgomery.prototype.convert = montConvert; 571 | Montgomery.prototype.revert = montRevert; 572 | Montgomery.prototype.reduce = montReduce; 573 | Montgomery.prototype.mulTo = montMulTo; 574 | Montgomery.prototype.sqrTo = montSqrTo; 575 | 576 | // (protected) true iff this is even 577 | function bnpIsEven() { 578 | return ((this.t > 0) ? (this[0] & 1) : this.s) == 0; 579 | } 580 | 581 | // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) 582 | function bnpExp(e, z) { 583 | if (e > 0xffffffff || e < 1) return BigInteger.ONE; 584 | var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e) - 1; 585 | g.copyTo(r); 586 | while (--i >= 0) { 587 | z.sqrTo(r, r2); 588 | if ((e & (1 << i)) > 0) z.mulTo(r2, g, r); 589 | else { 590 | var t = r; 591 | r = r2; 592 | r2 = t; 593 | } 594 | } 595 | return z.revert(r); 596 | } 597 | 598 | // (public) this^e % m, 0 <= e < 2^32 599 | function bnModPowInt(e, m) { 600 | var z; 601 | if (e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); 602 | return this.exp(e, z); 603 | } 604 | 605 | // protected 606 | BigInteger.prototype.copyTo = bnpCopyTo; 607 | BigInteger.prototype.fromInt = bnpFromInt; 608 | BigInteger.prototype.fromString = bnpFromString; 609 | BigInteger.prototype.clamp = bnpClamp; 610 | BigInteger.prototype.dlShiftTo = bnpDLShiftTo; 611 | BigInteger.prototype.drShiftTo = bnpDRShiftTo; 612 | BigInteger.prototype.lShiftTo = bnpLShiftTo; 613 | BigInteger.prototype.rShiftTo = bnpRShiftTo; 614 | BigInteger.prototype.subTo = bnpSubTo; 615 | BigInteger.prototype.multiplyTo = bnpMultiplyTo; 616 | BigInteger.prototype.squareTo = bnpSquareTo; 617 | BigInteger.prototype.divRemTo = bnpDivRemTo; 618 | BigInteger.prototype.invDigit = bnpInvDigit; 619 | BigInteger.prototype.isEven = bnpIsEven; 620 | BigInteger.prototype.exp = bnpExp; 621 | 622 | // public 623 | BigInteger.prototype.toString = bnToString; 624 | BigInteger.prototype.negate = bnNegate; 625 | BigInteger.prototype.abs = bnAbs; 626 | BigInteger.prototype.compareTo = bnCompareTo; 627 | BigInteger.prototype.bitLength = bnBitLength; 628 | BigInteger.prototype.mod = bnMod; 629 | BigInteger.prototype.modPowInt = bnModPowInt; 630 | 631 | // "constants" 632 | BigInteger.ZERO = nbv(0); 633 | BigInteger.ONE = nbv(1); 634 | -------------------------------------------------------------------------------- /src/assets/js/jsbn2.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2005-2009 Tom Wu 2 | // All Rights Reserved. 3 | // See "LICENSE" for details. 4 | 5 | // Extended JavaScript BN functions, required for RSA private ops. 6 | 7 | // Version 1.1: new BigInteger("0", 10) returns "proper" zero 8 | // Version 1.2: square() API, isProbablePrime fix 9 | 10 | // (public) 11 | function bnClone() { 12 | var r = nbi(); 13 | this.copyTo(r); 14 | return r; 15 | } 16 | 17 | // (public) return value as integer 18 | function bnIntValue() { 19 | if (this.s < 0) { 20 | if (this.t == 1) return this[0] - this.DV; 21 | else if (this.t == 0) return -1; 22 | } 23 | else if (this.t == 1) return this[0]; 24 | else if (this.t == 0) return 0; 25 | // assumes 16 < DB < 32 26 | return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0]; 27 | } 28 | 29 | // (public) return value as byte 30 | function bnByteValue() { 31 | return (this.t == 0) ? this.s : (this[0] << 24) >> 24; 32 | } 33 | 34 | // (public) return value as short (assumes DB>=16) 35 | function bnShortValue() { 36 | return (this.t == 0) ? this.s : (this[0] << 16) >> 16; 37 | } 38 | 39 | // (protected) return x s.t. r^x < DV 40 | function bnpChunkSize(r) { 41 | return Math.floor(Math.LN2 * this.DB / Math.log(r)); 42 | } 43 | 44 | // (public) 0 if this == 0, 1 if this > 0 45 | function bnSigNum() { 46 | if (this.s < 0) return -1; 47 | else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; 48 | else return 1; 49 | } 50 | 51 | // (protected) convert to radix string 52 | function bnpToRadix(b) { 53 | if (b == null) b = 10; 54 | if (this.signum() == 0 || b < 2 || b > 36) return "0"; 55 | var cs = this.chunkSize(b); 56 | var a = Math.pow(b, cs); 57 | var d = nbv(a), y = nbi(), z = nbi(), r = ""; 58 | this.divRemTo(d, y, z); 59 | while (y.signum() > 0) { 60 | r = (a + z.intValue()).toString(b).substr(1) + r; 61 | y.divRemTo(d, y, z); 62 | } 63 | return z.intValue().toString(b) + r; 64 | } 65 | 66 | // (protected) convert from radix string 67 | function bnpFromRadix(s, b) { 68 | this.fromInt(0); 69 | if (b == null) b = 10; 70 | var cs = this.chunkSize(b); 71 | var d = Math.pow(b, cs), mi = false, j = 0, w = 0; 72 | for (var i = 0; i < s.length; ++i) { 73 | var x = intAt(s, i); 74 | if (x < 0) { 75 | if (s.charAt(i) == "-" && this.signum() == 0) mi = true; 76 | continue; 77 | } 78 | w = b * w + x; 79 | if (++j >= cs) { 80 | this.dMultiply(d); 81 | this.dAddOffset(w, 0); 82 | j = 0; 83 | w = 0; 84 | } 85 | } 86 | if (j > 0) { 87 | this.dMultiply(Math.pow(b, j)); 88 | this.dAddOffset(w, 0); 89 | } 90 | if (mi) BigInteger.ZERO.subTo(this, this); 91 | } 92 | 93 | // (protected) alternate constructor 94 | function bnpFromNumber(a, b, c) { 95 | if ("number" == typeof b) { 96 | // new BigInteger(int,int,RNG) 97 | if (a < 2) this.fromInt(1); 98 | else { 99 | this.fromNumber(a, c); 100 | if (!this.testBit(a - 1)) // force MSB set 101 | this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this); 102 | if (this.isEven()) this.dAddOffset(1, 0); // force odd 103 | while (!this.isProbablePrime(b)) { 104 | this.dAddOffset(2, 0); 105 | if (this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a - 1), this); 106 | } 107 | } 108 | } 109 | else { 110 | // new BigInteger(int,RNG) 111 | var x = new Array(), t = a & 7; 112 | x.length = (a >> 3) + 1; 113 | b.nextBytes(x); 114 | if (t > 0) x[0] &= ((1 << t) - 1); else x[0] = 0; 115 | this.fromString(x, 256); 116 | } 117 | } 118 | 119 | // (public) convert to bigendian byte array 120 | function bnToByteArray() { 121 | var i = this.t, r = new Array(); 122 | r[0] = this.s; 123 | var p = this.DB - (i * this.DB) % 8, d, k = 0; 124 | if (i-- > 0) { 125 | if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) 126 | r[k++] = d | (this.s << (this.DB - p)); 127 | while (i >= 0) { 128 | if (p < 8) { 129 | d = (this[i] & ((1 << p) - 1)) << (8 - p); 130 | d |= this[--i] >> (p += this.DB - 8); 131 | } 132 | else { 133 | d = (this[i] >> (p -= 8)) & 0xff; 134 | if (p <= 0) { 135 | p += this.DB; 136 | --i; 137 | } 138 | } 139 | if ((d & 0x80) != 0) d |= -256; 140 | if (k == 0 && (this.s & 0x80) != (d & 0x80)) ++k; 141 | if (k > 0 || d != this.s) r[k++] = d; 142 | } 143 | } 144 | return r; 145 | } 146 | 147 | function bnEquals(a) { 148 | return (this.compareTo(a) == 0); 149 | } 150 | function bnMin(a) { 151 | return (this.compareTo(a) < 0) ? this : a; 152 | } 153 | function bnMax(a) { 154 | return (this.compareTo(a) > 0) ? this : a; 155 | } 156 | 157 | // (protected) r = this op a (bitwise) 158 | function bnpBitwiseTo(a, op, r) { 159 | var i, f, m = Math.min(a.t, this.t); 160 | for (i = 0; i < m; ++i) r[i] = op(this[i], a[i]); 161 | if (a.t < this.t) { 162 | f = a.s & this.DM; 163 | for (i = m; i < this.t; ++i) r[i] = op(this[i], f); 164 | r.t = this.t; 165 | } 166 | else { 167 | f = this.s & this.DM; 168 | for (i = m; i < a.t; ++i) r[i] = op(f, a[i]); 169 | r.t = a.t; 170 | } 171 | r.s = op(this.s, a.s); 172 | r.clamp(); 173 | } 174 | 175 | // (public) this & a 176 | function op_and(x, y) { 177 | return x & y; 178 | } 179 | function bnAnd(a) { 180 | var r = nbi(); 181 | this.bitwiseTo(a, op_and, r); 182 | return r; 183 | } 184 | 185 | // (public) this | a 186 | function op_or(x, y) { 187 | return x | y; 188 | } 189 | function bnOr(a) { 190 | var r = nbi(); 191 | this.bitwiseTo(a, op_or, r); 192 | return r; 193 | } 194 | 195 | // (public) this ^ a 196 | function op_xor(x, y) { 197 | return x ^ y; 198 | } 199 | function bnXor(a) { 200 | var r = nbi(); 201 | this.bitwiseTo(a, op_xor, r); 202 | return r; 203 | } 204 | 205 | // (public) this & ~a 206 | function op_andnot(x, y) { 207 | return x & ~y; 208 | } 209 | function bnAndNot(a) { 210 | var r = nbi(); 211 | this.bitwiseTo(a, op_andnot, r); 212 | return r; 213 | } 214 | 215 | // (public) ~this 216 | function bnNot() { 217 | var r = nbi(); 218 | for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i]; 219 | r.t = this.t; 220 | r.s = ~this.s; 221 | return r; 222 | } 223 | 224 | // (public) this << n 225 | function bnShiftLeft(n) { 226 | var r = nbi(); 227 | if (n < 0) this.rShiftTo(-n, r); else this.lShiftTo(n, r); 228 | return r; 229 | } 230 | 231 | // (public) this >> n 232 | function bnShiftRight(n) { 233 | var r = nbi(); 234 | if (n < 0) this.lShiftTo(-n, r); else this.rShiftTo(n, r); 235 | return r; 236 | } 237 | 238 | // return index of lowest 1-bit in x, x < 2^31 239 | function lbit(x) { 240 | if (x == 0) return -1; 241 | var r = 0; 242 | if ((x & 0xffff) == 0) { 243 | x >>= 16; 244 | r += 16; 245 | } 246 | if ((x & 0xff) == 0) { 247 | x >>= 8; 248 | r += 8; 249 | } 250 | if ((x & 0xf) == 0) { 251 | x >>= 4; 252 | r += 4; 253 | } 254 | if ((x & 3) == 0) { 255 | x >>= 2; 256 | r += 2; 257 | } 258 | if ((x & 1) == 0) ++r; 259 | return r; 260 | } 261 | 262 | // (public) returns index of lowest 1-bit (or -1 if none) 263 | function bnGetLowestSetBit() { 264 | for (var i = 0; i < this.t; ++i) 265 | if (this[i] != 0) return i * this.DB + lbit(this[i]); 266 | if (this.s < 0) return this.t * this.DB; 267 | return -1; 268 | } 269 | 270 | // return number of 1 bits in x 271 | function cbit(x) { 272 | var r = 0; 273 | while (x != 0) { 274 | x &= x - 1; 275 | ++r; 276 | } 277 | return r; 278 | } 279 | 280 | // (public) return number of set bits 281 | function bnBitCount() { 282 | var r = 0, x = this.s & this.DM; 283 | for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x); 284 | return r; 285 | } 286 | 287 | // (public) true iff nth bit is set 288 | function bnTestBit(n) { 289 | var j = Math.floor(n / this.DB); 290 | if (j >= this.t) return (this.s != 0); 291 | return ((this[j] & (1 << (n % this.DB))) != 0); 292 | } 293 | 294 | // (protected) this op (1<>= this.DB; 323 | } 324 | if (a.t < this.t) { 325 | c += a.s; 326 | while (i < this.t) { 327 | c += this[i]; 328 | r[i++] = c & this.DM; 329 | c >>= this.DB; 330 | } 331 | c += this.s; 332 | } 333 | else { 334 | c += this.s; 335 | while (i < a.t) { 336 | c += a[i]; 337 | r[i++] = c & this.DM; 338 | c >>= this.DB; 339 | } 340 | c += a.s; 341 | } 342 | r.s = (c < 0) ? -1 : 0; 343 | if (c > 0) r[i++] = c; 344 | else if (c < -1) r[i++] = this.DV + c; 345 | r.t = i; 346 | r.clamp(); 347 | } 348 | 349 | // (public) this + a 350 | function bnAdd(a) { 351 | var r = nbi(); 352 | this.addTo(a, r); 353 | return r; 354 | } 355 | 356 | // (public) this - a 357 | function bnSubtract(a) { 358 | var r = nbi(); 359 | this.subTo(a, r); 360 | return r; 361 | } 362 | 363 | // (public) this * a 364 | function bnMultiply(a) { 365 | var r = nbi(); 366 | this.multiplyTo(a, r); 367 | return r; 368 | } 369 | 370 | // (public) this^2 371 | function bnSquare() { 372 | var r = nbi(); 373 | this.squareTo(r); 374 | return r; 375 | } 376 | 377 | // (public) this / a 378 | function bnDivide(a) { 379 | var r = nbi(); 380 | this.divRemTo(a, r, null); 381 | return r; 382 | } 383 | 384 | // (public) this % a 385 | function bnRemainder(a) { 386 | var r = nbi(); 387 | this.divRemTo(a, null, r); 388 | return r; 389 | } 390 | 391 | // (public) [this/a,this%a] 392 | function bnDivideAndRemainder(a) { 393 | var q = nbi(), r = nbi(); 394 | this.divRemTo(a, q, r); 395 | return new Array(q, r); 396 | } 397 | 398 | // (protected) this *= n, this >= 0, 1 < n < DV 399 | function bnpDMultiply(n) { 400 | this[this.t] = this.am(0, n - 1, this, 0, 0, this.t); 401 | ++this.t; 402 | this.clamp(); 403 | } 404 | 405 | // (protected) this += n << w words, this >= 0 406 | function bnpDAddOffset(n, w) { 407 | if (n == 0) return; 408 | while (this.t <= w) this[this.t++] = 0; 409 | this[w] += n; 410 | while (this[w] >= this.DV) { 411 | this[w] -= this.DV; 412 | if (++w >= this.t) this[this.t++] = 0; 413 | ++this[w]; 414 | } 415 | } 416 | 417 | // A "null" reducer 418 | function NullExp() { 419 | } 420 | function nNop(x) { 421 | return x; 422 | } 423 | function nMulTo(x, y, r) { 424 | x.multiplyTo(y, r); 425 | } 426 | function nSqrTo(x, r) { 427 | x.squareTo(r); 428 | } 429 | 430 | NullExp.prototype.convert = nNop; 431 | NullExp.prototype.revert = nNop; 432 | NullExp.prototype.mulTo = nMulTo; 433 | NullExp.prototype.sqrTo = nSqrTo; 434 | 435 | // (public) this^e 436 | function bnPow(e) { 437 | return this.exp(e, new NullExp()); 438 | } 439 | 440 | // (protected) r = lower n words of "this * a", a.t <= n 441 | // "this" should be the larger one if appropriate. 442 | function bnpMultiplyLowerTo(a, n, r) { 443 | var i = Math.min(this.t + a.t, n); 444 | r.s = 0; // assumes a,this >= 0 445 | r.t = i; 446 | while (i > 0) r[--i] = 0; 447 | var j; 448 | for (j = r.t - this.t; i < j; ++i) r[i + this.t] = this.am(0, a[i], r, i, 0, this.t); 449 | for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i); 450 | r.clamp(); 451 | } 452 | 453 | // (protected) r = "this * a" without lower n words, n > 0 454 | // "this" should be the larger one if appropriate. 455 | function bnpMultiplyUpperTo(a, n, r) { 456 | --n; 457 | var i = r.t = this.t + a.t - n; 458 | r.s = 0; // assumes a,this >= 0 459 | while (--i >= 0) r[i] = 0; 460 | for (i = Math.max(n - this.t, 0); i < a.t; ++i) 461 | r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n); 462 | r.clamp(); 463 | r.drShiftTo(1, r); 464 | } 465 | 466 | // Barrett modular reduction 467 | function Barrett(m) { 468 | // setup Barrett 469 | this.r2 = nbi(); 470 | this.q3 = nbi(); 471 | BigInteger.ONE.dlShiftTo(2 * m.t, this.r2); 472 | this.mu = this.r2.divide(m); 473 | this.m = m; 474 | } 475 | 476 | function barrettConvert(x) { 477 | if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m); 478 | else if (x.compareTo(this.m) < 0) return x; 479 | else { 480 | var r = nbi(); 481 | x.copyTo(r); 482 | this.reduce(r); 483 | return r; 484 | } 485 | } 486 | 487 | function barrettRevert(x) { 488 | return x; 489 | } 490 | 491 | // x = x mod m (HAC 14.42) 492 | function barrettReduce(x) { 493 | x.drShiftTo(this.m.t - 1, this.r2); 494 | if (x.t > this.m.t + 1) { 495 | x.t = this.m.t + 1; 496 | x.clamp(); 497 | } 498 | this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3); 499 | this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2); 500 | while (x.compareTo(this.r2) < 0) x.dAddOffset(1, this.m.t + 1); 501 | x.subTo(this.r2, x); 502 | while (x.compareTo(this.m) >= 0) x.subTo(this.m, x); 503 | } 504 | 505 | // r = x^2 mod m; x != r 506 | function barrettSqrTo(x, r) { 507 | x.squareTo(r); 508 | this.reduce(r); 509 | } 510 | 511 | // r = x*y mod m; x,y != r 512 | function barrettMulTo(x, y, r) { 513 | x.multiplyTo(y, r); 514 | this.reduce(r); 515 | } 516 | 517 | Barrett.prototype.convert = barrettConvert; 518 | Barrett.prototype.revert = barrettRevert; 519 | Barrett.prototype.reduce = barrettReduce; 520 | Barrett.prototype.mulTo = barrettMulTo; 521 | Barrett.prototype.sqrTo = barrettSqrTo; 522 | 523 | // (public) this^e % m (HAC 14.85) 524 | function bnModPow(e, m) { 525 | var i = e.bitLength(), k, r = nbv(1), z; 526 | if (i <= 0) return r; 527 | else if (i < 18) k = 1; 528 | else if (i < 48) k = 3; 529 | else if (i < 144) k = 4; 530 | else if (i < 768) k = 5; 531 | else k = 6; 532 | if (i < 8) 533 | z = new Classic(m); 534 | else if (m.isEven()) 535 | z = new Barrett(m); 536 | else 537 | z = new Montgomery(m); 538 | 539 | // precomputation 540 | var g = new Array(), n = 3, k1 = k - 1, km = (1 << k) - 1; 541 | g[1] = z.convert(this); 542 | if (k > 1) { 543 | var g2 = nbi(); 544 | z.sqrTo(g[1], g2); 545 | while (n <= km) { 546 | g[n] = nbi(); 547 | z.mulTo(g2, g[n - 2], g[n]); 548 | n += 2; 549 | } 550 | } 551 | 552 | var j = e.t - 1, w, is1 = true, r2 = nbi(), t; 553 | i = nbits(e[j]) - 1; 554 | while (j >= 0) { 555 | if (i >= k1) w = (e[j] >> (i - k1)) & km; 556 | else { 557 | w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i); 558 | if (j > 0) w |= e[j - 1] >> (this.DB + i - k1); 559 | } 560 | 561 | n = k; 562 | while ((w & 1) == 0) { 563 | w >>= 1; 564 | --n; 565 | } 566 | if ((i -= n) < 0) { 567 | i += this.DB; 568 | --j; 569 | } 570 | if (is1) { // ret == 1, don't bother squaring or multiplying it 571 | g[w].copyTo(r); 572 | is1 = false; 573 | } 574 | else { 575 | while (n > 1) { 576 | z.sqrTo(r, r2); 577 | z.sqrTo(r2, r); 578 | n -= 2; 579 | } 580 | if (n > 0) z.sqrTo(r, r2); else { 581 | t = r; 582 | r = r2; 583 | r2 = t; 584 | } 585 | z.mulTo(r2, g[w], r); 586 | } 587 | 588 | while (j >= 0 && (e[j] & (1 << i)) == 0) { 589 | z.sqrTo(r, r2); 590 | t = r; 591 | r = r2; 592 | r2 = t; 593 | if (--i < 0) { 594 | i = this.DB - 1; 595 | --j; 596 | } 597 | } 598 | } 599 | return z.revert(r); 600 | } 601 | 602 | // (public) gcd(this,a) (HAC 14.54) 603 | function bnGCD(a) { 604 | var x = (this.s < 0) ? this.negate() : this.clone(); 605 | var y = (a.s < 0) ? a.negate() : a.clone(); 606 | if (x.compareTo(y) < 0) { 607 | var t = x; 608 | x = y; 609 | y = t; 610 | } 611 | var i = x.getLowestSetBit(), g = y.getLowestSetBit(); 612 | if (g < 0) return x; 613 | if (i < g) g = i; 614 | if (g > 0) { 615 | x.rShiftTo(g, x); 616 | y.rShiftTo(g, y); 617 | } 618 | while (x.signum() > 0) { 619 | if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x); 620 | if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y); 621 | if (x.compareTo(y) >= 0) { 622 | x.subTo(y, x); 623 | x.rShiftTo(1, x); 624 | } 625 | else { 626 | y.subTo(x, y); 627 | y.rShiftTo(1, y); 628 | } 629 | } 630 | if (g > 0) y.lShiftTo(g, y); 631 | return y; 632 | } 633 | 634 | // (protected) this % n, n < 2^26 635 | function bnpModInt(n) { 636 | if (n <= 0) return 0; 637 | var d = this.DV % n, r = (this.s < 0) ? n - 1 : 0; 638 | if (this.t > 0) 639 | if (d == 0) r = this[0] % n; 640 | else for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n; 641 | return r; 642 | } 643 | 644 | // (public) 1/this % m (HAC 14.61) 645 | function bnModInverse(m) { 646 | var ac = m.isEven(); 647 | if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; 648 | var u = m.clone(), v = this.clone(); 649 | var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); 650 | while (u.signum() != 0) { 651 | while (u.isEven()) { 652 | u.rShiftTo(1, u); 653 | if (ac) { 654 | if (!a.isEven() || !b.isEven()) { 655 | a.addTo(this, a); 656 | b.subTo(m, b); 657 | } 658 | a.rShiftTo(1, a); 659 | } 660 | else if (!b.isEven()) b.subTo(m, b); 661 | b.rShiftTo(1, b); 662 | } 663 | while (v.isEven()) { 664 | v.rShiftTo(1, v); 665 | if (ac) { 666 | if (!c.isEven() || !d.isEven()) { 667 | c.addTo(this, c); 668 | d.subTo(m, d); 669 | } 670 | c.rShiftTo(1, c); 671 | } 672 | else if (!d.isEven()) d.subTo(m, d); 673 | d.rShiftTo(1, d); 674 | } 675 | if (u.compareTo(v) >= 0) { 676 | u.subTo(v, u); 677 | if (ac) a.subTo(c, a); 678 | b.subTo(d, b); 679 | } 680 | else { 681 | v.subTo(u, v); 682 | if (ac) c.subTo(a, c); 683 | d.subTo(b, d); 684 | } 685 | } 686 | if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; 687 | if (d.compareTo(m) >= 0) return d.subtract(m); 688 | if (d.signum() < 0) d.addTo(m, d); else return d; 689 | if (d.signum() < 0) return d.add(m); else return d; 690 | } 691 | 692 | var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]; 693 | var lplim = (1 << 26) / lowprimes[lowprimes.length - 1]; 694 | 695 | // (public) test primality with certainty >= 1-.5^t 696 | function bnIsProbablePrime(t) { 697 | var i, x = this.abs(); 698 | if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) { 699 | for (i = 0; i < lowprimes.length; ++i) 700 | if (x[0] == lowprimes[i]) return true; 701 | return false; 702 | } 703 | if (x.isEven()) return false; 704 | i = 1; 705 | while (i < lowprimes.length) { 706 | var m = lowprimes[i], j = i + 1; 707 | while (j < lowprimes.length && m < lplim) m *= lowprimes[j++]; 708 | m = x.modInt(m); 709 | while (i < j) if (m % lowprimes[i++] == 0) return false; 710 | } 711 | return x.millerRabin(t); 712 | } 713 | 714 | // (protected) true if probably prime (HAC 4.24, Miller-Rabin) 715 | function bnpMillerRabin(t) { 716 | var n1 = this.subtract(BigInteger.ONE); 717 | var k = n1.getLowestSetBit(); 718 | if (k <= 0) return false; 719 | var r = n1.shiftRight(k); 720 | t = (t + 1) >> 1; 721 | if (t > lowprimes.length) t = lowprimes.length; 722 | var a = nbi(); 723 | for (var i = 0; i < t; ++i) { 724 | //Pick bases at random, instead of starting at 2 725 | a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]); 726 | var y = a.modPow(r, this); 727 | if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { 728 | var j = 1; 729 | while (j++ < k && y.compareTo(n1) != 0) { 730 | y = y.modPowInt(2, this); 731 | if (y.compareTo(BigInteger.ONE) == 0) return false; 732 | } 733 | if (y.compareTo(n1) != 0) return false; 734 | } 735 | } 736 | return true; 737 | } 738 | 739 | // protected 740 | BigInteger.prototype.chunkSize = bnpChunkSize; 741 | BigInteger.prototype.toRadix = bnpToRadix; 742 | BigInteger.prototype.fromRadix = bnpFromRadix; 743 | BigInteger.prototype.fromNumber = bnpFromNumber; 744 | BigInteger.prototype.bitwiseTo = bnpBitwiseTo; 745 | BigInteger.prototype.changeBit = bnpChangeBit; 746 | BigInteger.prototype.addTo = bnpAddTo; 747 | BigInteger.prototype.dMultiply = bnpDMultiply; 748 | BigInteger.prototype.dAddOffset = bnpDAddOffset; 749 | BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; 750 | BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; 751 | BigInteger.prototype.modInt = bnpModInt; 752 | BigInteger.prototype.millerRabin = bnpMillerRabin; 753 | 754 | // public 755 | BigInteger.prototype.clone = bnClone; 756 | BigInteger.prototype.intValue = bnIntValue; 757 | BigInteger.prototype.byteValue = bnByteValue; 758 | BigInteger.prototype.shortValue = bnShortValue; 759 | BigInteger.prototype.signum = bnSigNum; 760 | BigInteger.prototype.toByteArray = bnToByteArray; 761 | BigInteger.prototype.equals = bnEquals; 762 | BigInteger.prototype.min = bnMin; 763 | BigInteger.prototype.max = bnMax; 764 | BigInteger.prototype.and = bnAnd; 765 | BigInteger.prototype.or = bnOr; 766 | BigInteger.prototype.xor = bnXor; 767 | BigInteger.prototype.andNot = bnAndNot; 768 | BigInteger.prototype.not = bnNot; 769 | BigInteger.prototype.shiftLeft = bnShiftLeft; 770 | BigInteger.prototype.shiftRight = bnShiftRight; 771 | BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; 772 | BigInteger.prototype.bitCount = bnBitCount; 773 | BigInteger.prototype.testBit = bnTestBit; 774 | BigInteger.prototype.setBit = bnSetBit; 775 | BigInteger.prototype.clearBit = bnClearBit; 776 | BigInteger.prototype.flipBit = bnFlipBit; 777 | BigInteger.prototype.add = bnAdd; 778 | BigInteger.prototype.subtract = bnSubtract; 779 | BigInteger.prototype.multiply = bnMultiply; 780 | BigInteger.prototype.divide = bnDivide; 781 | BigInteger.prototype.remainder = bnRemainder; 782 | BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; 783 | BigInteger.prototype.modPow = bnModPow; 784 | BigInteger.prototype.modInverse = bnModInverse; 785 | BigInteger.prototype.pow = bnPow; 786 | BigInteger.prototype.gcd = bnGCD; 787 | BigInteger.prototype.isProbablePrime = bnIsProbablePrime; 788 | 789 | // JSBN-specific extension 790 | BigInteger.prototype.square = bnSquare; 791 | 792 | // BigInteger interfaces not implemented in jsbn: 793 | 794 | // BigInteger(int signum, byte[] magnitude) 795 | // double doubleValue() 796 | // float floatValue() 797 | // int hashCode() 798 | // long longValue() 799 | // static BigInteger valueOf(long val) 800 | -------------------------------------------------------------------------------- /src/assets/js/sjcl.js: -------------------------------------------------------------------------------- 1 | "use strict";var sjcl={cipher:{},hash:{},keyexchange:{},mode:{},misc:{},codec:{},exception:{corrupt:function(a){this.toString=function(){return"CORRUPT: "+this.message};this.message=a},invalid:function(a){this.toString=function(){return"INVALID: "+this.message};this.message=a},bug:function(a){this.toString=function(){return"BUG: "+this.message};this.message=a},notReady:function(a){this.toString=function(){return"NOT READY: "+this.message};this.message=a}}}; 2 | sjcl.cipher.aes=function(a){this.s[0][0][0]||this.O();var b,c,d,e,f=this.s[0][4],g=this.s[1];b=a.length;var h=1;if(4!==b&&6!==b&&8!==b)throw new sjcl.exception.invalid("invalid aes key size");this.b=[d=a.slice(0),e=[]];for(a=b;a<4*b+28;a++){c=d[a-1];if(0===a%b||8===b&&4===a%b)c=f[c>>>24]<<24^f[c>>16&255]<<16^f[c>>8&255]<<8^f[c&255],0===a%b&&(c=c<<8^c>>>24^h<<24,h=h<<1^283*(h>>7));d[a]=d[a-b]^c}for(b=0;a;b++,a--)c=d[b&3?a:a-4],e[b]=4>=a||4>b?c:g[0][f[c>>>24]]^g[1][f[c>>16&255]]^g[2][f[c>>8&255]]^g[3][f[c& 3 | 255]]}; 4 | sjcl.cipher.aes.prototype={encrypt:function(a){return t(this,a,0)},decrypt:function(a){return t(this,a,1)},s:[[[],[],[],[],[]],[[],[],[],[],[]]],O:function(){var a=this.s[0],b=this.s[1],c=a[4],d=b[4],e,f,g,h=[],k=[],l,n,m,p;for(e=0;0x100>e;e++)k[(h[e]=e<<1^283*(e>>7))^e]=e;for(f=g=0;!c[f];f^=l||1,g=k[g]||1)for(m=g^g<<1^g<<2^g<<3^g<<4,m=m>>8^m&255^99,c[f]=m,d[m]=f,n=h[e=h[l=h[f]]],p=0x1010101*n^0x10001*e^0x101*l^0x1010100*f,n=0x101*h[m]^0x1010100*m,e=0;4>e;e++)a[e][f]=n=n<<24^n>>>8,b[e][m]=p=p<<24^p>>>8;for(e= 5 | 0;5>e;e++)a[e]=a[e].slice(0),b[e]=b[e].slice(0)}}; 6 | function t(a,b,c){if(4!==b.length)throw new sjcl.exception.invalid("invalid aes block size");var d=a.b[c],e=b[0]^d[0],f=b[c?3:1]^d[1],g=b[2]^d[2];b=b[c?1:3]^d[3];var h,k,l,n=d.length/4-2,m,p=4,r=[0,0,0,0];h=a.s[c];a=h[0];var q=h[1],v=h[2],w=h[3],x=h[4];for(m=0;m>>24]^q[f>>16&255]^v[g>>8&255]^w[b&255]^d[p],k=a[f>>>24]^q[g>>16&255]^v[b>>8&255]^w[e&255]^d[p+1],l=a[g>>>24]^q[b>>16&255]^v[e>>8&255]^w[f&255]^d[p+2],b=a[b>>>24]^q[e>>16&255]^v[f>>8&255]^w[g&255]^d[p+3],p+=4,e=h,f=k,g=l;for(m= 7 | 0;4>m;m++)r[c?3&-m:m]=x[e>>>24]<<24^x[f>>16&255]<<16^x[g>>8&255]<<8^x[b&255]^d[p++],h=e,e=f,f=g,g=b,b=h;return r} 8 | sjcl.bitArray={bitSlice:function(a,b,c){a=sjcl.bitArray.$(a.slice(b/32),32-(b&31)).slice(1);return void 0===c?a:sjcl.bitArray.clamp(a,c-b)},extract:function(a,b,c){var d=Math.floor(-b-c&31);return((b+c-1^b)&-32?a[b/32|0]<<32-d^a[b/32+1|0]>>>d:a[b/32|0]>>>d)&(1<>b-1,1));return a},partial:function(a,b,c){return 32===a?b:(c?b|0:b<<32-a)+0x10000000000*a},getPartial:function(a){return Math.round(a/0x10000000000)||32},equal:function(a,b){if(sjcl.bitArray.bitLength(a)!==sjcl.bitArray.bitLength(b))return!1;var c=0,d;for(d=0;d>>b),c=a[e]<<32-b;e=a.length?a[a.length-1]:0;a=sjcl.bitArray.getPartial(e);d.push(sjcl.bitArray.partial(b+a&31,32>>24|c>>>8&0xff00|(c&0xff00)<<8|c<<24;return a}}; 11 | sjcl.codec.utf8String={fromBits:function(a){var b="",c=sjcl.bitArray.bitLength(a),d,e;for(d=0;d>>24),e<<=8;return decodeURIComponent(escape(b))},toBits:function(a){a=unescape(encodeURIComponent(a));var b=[],c,d=0;for(c=0;c>>g)>>>e),gn){if(!b)try{return sjcl.codec.base32hex.toBits(a)}catch(p){}throw new sjcl.exception.invalid("this isn't "+m+"!");}h>e?(h-=e,f.push(l^n>>>h),l=n<>>e)>>>26),6>e?(g=a[c]<<6-e,e+=26,c++):(g<<=6,e-=6);for(;d.length&3&&!b;)d+="=";return d},toBits:function(a,b){a=a.replace(/\s|=/g,"");var c=[],d,e=0,f=sjcl.codec.base64.B,g=0,h;b&&(f=f.substr(0,62)+"-_");for(d=0;dh)throw new sjcl.exception.invalid("this isn't base64!");26>>e),g=h<<32-e):(e+=6,g^=h<<32-e)}e&56&&c.push(sjcl.bitArray.partial(e&56,g,1));return c}};sjcl.codec.base64url={fromBits:function(a){return sjcl.codec.base64.fromBits(a,1,1)},toBits:function(a){return sjcl.codec.base64.toBits(a,1)}};sjcl.hash.sha256=function(a){this.b[0]||this.O();a?(this.F=a.F.slice(0),this.A=a.A.slice(0),this.l=a.l):this.reset()};sjcl.hash.sha256.hash=function(a){return(new sjcl.hash.sha256).update(a).finalize()}; 18 | sjcl.hash.sha256.prototype={blockSize:512,reset:function(){this.F=this.Y.slice(0);this.A=[];this.l=0;return this},update:function(a){"string"===typeof a&&(a=sjcl.codec.utf8String.toBits(a));var b,c=this.A=sjcl.bitArray.concat(this.A,a);b=this.l;a=this.l=b+sjcl.bitArray.bitLength(a);if(0x1fffffffffffffb;c++){e=!0;for(d=2;d*d<=c;d++)if(0===c%d){e= 20 | !1;break}e&&(8>b&&(this.Y[b]=a(Math.pow(c,.5))),this.b[b]=a(Math.pow(c,1/3)),b++)}}}; 21 | function u(a,b){var c,d,e,f=a.F,g=a.b,h=f[0],k=f[1],l=f[2],n=f[3],m=f[4],p=f[5],r=f[6],q=f[7];for(c=0;64>c;c++)16>c?d=b[c]:(d=b[c+1&15],e=b[c+14&15],d=b[c&15]=(d>>>7^d>>>18^d>>>3^d<<25^d<<14)+(e>>>17^e>>>19^e>>>10^e<<15^e<<13)+b[c&15]+b[c+9&15]|0),d=d+q+(m>>>6^m>>>11^m>>>25^m<<26^m<<21^m<<7)+(r^m&(p^r))+g[c],q=r,r=p,p=m,m=n+d|0,n=l,l=k,k=h,h=d+(k&l^n&(k^l))+(k>>>2^k>>>13^k>>>22^k<<30^k<<19^k<<10)|0;f[0]=f[0]+h|0;f[1]=f[1]+k|0;f[2]=f[2]+l|0;f[3]=f[3]+n|0;f[4]=f[4]+m|0;f[5]=f[5]+p|0;f[6]=f[6]+r|0;f[7]= 22 | f[7]+q|0} 23 | sjcl.mode.ccm={name:"ccm",G:[],listenProgress:function(a){sjcl.mode.ccm.G.push(a)},unListenProgress:function(a){a=sjcl.mode.ccm.G.indexOf(a);-1k)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(f=2;4>f&&l>>>8*f;f++);f<15-k&&(f=15-k);c=h.clamp(c, 24 | 8*(15-f));b=sjcl.mode.ccm.V(a,b,c,d,e,f);g=sjcl.mode.ccm.C(a,g,c,b,e,f);return h.concat(g.data,g.tag)},decrypt:function(a,b,c,d,e){e=e||64;d=d||[];var f=sjcl.bitArray,g=f.bitLength(c)/8,h=f.bitLength(b),k=f.clamp(b,h-e),l=f.bitSlice(b,h-e),h=(h-e)/8;if(7>g)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(b=2;4>b&&h>>>8*b;b++);b<15-g&&(b=15-g);c=f.clamp(c,8*(15-b));k=sjcl.mode.ccm.C(a,k,c,l,e,b);a=sjcl.mode.ccm.V(a,k.data,c,d,e,b);if(!f.equal(k.tag,a))throw new sjcl.exception.corrupt("ccm: tag doesn't match"); 25 | return k.data},na:function(a,b,c,d,e,f){var g=[],h=sjcl.bitArray,k=h.i;d=[h.partial(8,(b.length?64:0)|d-2<<2|f-1)];d=h.concat(d,c);d[3]|=e;d=a.encrypt(d);if(b.length)for(c=h.bitLength(b)/8,65279>=c?g=[h.partial(16,c)]:0xffffffff>=c&&(g=h.concat([h.partial(16,65534)],[c])),g=h.concat(g,b),b=0;be||16n&&(sjcl.mode.ccm.fa(g/ 27 | k),n+=m),c[3]++,e=a.encrypt(c),b[g]^=e[0],b[g+1]^=e[1],b[g+2]^=e[2],b[g+3]^=e[3];return{tag:d,data:h.clamp(b,l)}}}; 28 | sjcl.mode.ocb2={name:"ocb2",encrypt:function(a,b,c,d,e,f){if(128!==sjcl.bitArray.bitLength(c))throw new sjcl.exception.invalid("ocb iv must be 128 bits");var g,h=sjcl.mode.ocb2.S,k=sjcl.bitArray,l=k.i,n=[0,0,0,0];c=h(a.encrypt(c));var m,p=[];d=d||[];e=e||64;for(g=0;g+4e.bitLength(c)&&(h=f(h,d(h)),c=e.concat(c,[-2147483648,0,0,0]));g=f(g,c); 31 | return a.encrypt(f(d(f(h,d(h))),g))},S:function(a){return[a[0]<<1^a[1]>>>31,a[1]<<1^a[2]>>>31,a[2]<<1^a[3]>>>31,a[3]<<1^135*(a[0]>>>31)]}}; 32 | sjcl.mode.gcm={name:"gcm",encrypt:function(a,b,c,d,e){var f=b.slice(0);b=sjcl.bitArray;d=d||[];a=sjcl.mode.gcm.C(!0,a,f,d,c,e||128);return b.concat(a.data,a.tag)},decrypt:function(a,b,c,d,e){var f=b.slice(0),g=sjcl.bitArray,h=g.bitLength(f);e=e||128;d=d||[];e<=h?(b=g.bitSlice(f,h-e),f=g.bitSlice(f,0,h-e)):(b=f,f=[]);a=sjcl.mode.gcm.C(!1,a,f,d,c,e);if(!g.equal(a.tag,b))throw new sjcl.exception.corrupt("gcm: tag doesn't match");return a.data},ka:function(a,b){var c,d,e,f,g,h=sjcl.bitArray.i;e=[0,0, 33 | 0,0];f=b.slice(0);for(c=0;128>c;c++){(d=0!==(a[Math.floor(c/32)]&1<<31-c%32))&&(e=h(e,f));g=0!==(f[3]&1);for(d=3;0>>1|(f[d-1]&1)<<31;f[0]>>>=1;g&&(f[0]^=-0x1f000000)}return e},j:function(a,b,c){var d,e=c.length;b=b.slice(0);for(d=0;de&&(a=b.hash(a));for(d=0;dd||0>c)throw new sjcl.exception.invalid("invalid params to pbkdf2");"string"===typeof a&&(a=sjcl.codec.utf8String.toBits(a));"string"===typeof b&&(b=sjcl.codec.utf8String.toBits(b));e=e||sjcl.misc.hmac;a=new e(a);var f,g,h,k,l=[],n=sjcl.bitArray;for(k=1;32*l.length<(d||1);k++){e=f=a.encrypt(n.concat(b,[k]));for(g=1;gg;g++)e.push(0x100000000*Math.random()|0);for(g=0;g=1<this.o&&(this.o= 40 | f);this.P++;this.b=sjcl.hash.sha256.hash(this.b.concat(e));this.L=new sjcl.cipher.aes(this.b);for(d=0;4>d&&(this.h[d]=this.h[d]+1|0,!this.h[d]);d++);}for(d=0;d>>1;this.c[g].update([d,this.N++,2,b,f,a.length].concat(a))}break;case "string":void 0===b&&(b=a.length);this.c[g].update([d,this.N++,3,b,f,a.length]);this.c[g].update(a);break;default:k=1}if(k)throw new sjcl.exception.bug("random: addEntropy only supports number, array of numbers or string");this.m[g]+=b;this.f+=b;h===this.u&&(this.isReady()!==this.u&&A("seeded",Math.max(this.o,this.f)),A("progress",this.getProgress()))}, 43 | isReady:function(a){a=this.T[void 0!==a?a:this.M];return this.o&&this.o>=a?this.m[0]>this.ba&&(new Date).valueOf()>this.Z?this.J|this.I:this.I:this.f>=a?this.J|this.u:this.u},getProgress:function(a){a=this.T[a?a:this.M];return this.o>=a?1:this.f>a?1:this.f/a},startCollectors:function(){if(!this.D){this.a={loadTimeCollector:B(this,this.ma),mouseCollector:B(this,this.oa),keyboardCollector:B(this,this.la),accelerometerCollector:B(this,this.ea),touchCollector:B(this,this.qa)};if(window.addEventListener)window.addEventListener("load", 44 | this.a.loadTimeCollector,!1),window.addEventListener("mousemove",this.a.mouseCollector,!1),window.addEventListener("keypress",this.a.keyboardCollector,!1),window.addEventListener("devicemotion",this.a.accelerometerCollector,!1),window.addEventListener("touchmove",this.a.touchCollector,!1);else if(document.attachEvent)document.attachEvent("onload",this.a.loadTimeCollector),document.attachEvent("onmousemove",this.a.mouseCollector),document.attachEvent("keypress",this.a.keyboardCollector);else throw new sjcl.exception.bug("can't attach event"); 45 | this.D=!0}},stopCollectors:function(){this.D&&(window.removeEventListener?(window.removeEventListener("load",this.a.loadTimeCollector,!1),window.removeEventListener("mousemove",this.a.mouseCollector,!1),window.removeEventListener("keypress",this.a.keyboardCollector,!1),window.removeEventListener("devicemotion",this.a.accelerometerCollector,!1),window.removeEventListener("touchmove",this.a.touchCollector,!1)):document.detachEvent&&(document.detachEvent("onload",this.a.loadTimeCollector),document.detachEvent("onmousemove", 46 | this.a.mouseCollector),document.detachEvent("keypress",this.a.keyboardCollector)),this.D=!1)},addEventListener:function(a,b){this.K[a][this.ga++]=b},removeEventListener:function(a,b){var c,d,e=this.K[a],f=[];for(d in e)e.hasOwnProperty(d)&&e[d]===b&&f.push(d);for(c=0;cb&&(a.h[b]=a.h[b]+1|0,!a.h[b]);b++);return a.L.encrypt(a.h)} 49 | function B(a,b){return function(){b.apply(a,arguments)}}sjcl.random=new sjcl.prng(6); 50 | a:try{var D,E,F,G;if(G="undefined"!==typeof module&&module.exports){var H;try{H=require("crypto")}catch(a){H=null}G=E=H}if(G&&E.randomBytes)D=E.randomBytes(128),D=new Uint32Array((new Uint8Array(D)).buffer),sjcl.random.addEntropy(D,1024,"crypto['randomBytes']");else if("undefined"!==typeof window&&"undefined"!==typeof Uint32Array){F=new Uint32Array(32);if(window.crypto&&window.crypto.getRandomValues)window.crypto.getRandomValues(F);else if(window.msCrypto&&window.msCrypto.getRandomValues)window.msCrypto.getRandomValues(F); 51 | else break a;sjcl.random.addEntropy(F,1024,"crypto['getRandomValues']")}}catch(a){"undefined"!==typeof window&&window.console&&(console.log("There was an error collecting entropy from the browser:"),console.log(a))} 52 | sjcl.json={defaults:{v:1,iter:1E4,ks:128,ts:64,mode:"ccm",adata:"",cipher:"aes"},ja:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json,f=e.g({iv:sjcl.random.randomWords(4,0)},e.defaults),g;e.g(f,c);c=f.adata;"string"===typeof f.salt&&(f.salt=sjcl.codec.base64.toBits(f.salt));"string"===typeof f.iv&&(f.iv=sjcl.codec.base64.toBits(f.iv));if(!sjcl.mode[f.mode]||!sjcl.cipher[f.cipher]||"string"===typeof a&&100>=f.iter||64!==f.ts&&96!==f.ts&&128!==f.ts||128!==f.ks&&192!==f.ks&&0x100!==f.ks||2>f.iv.length|| 53 | 4=b.iter||64!==b.ts&&96!==b.ts&&128!==b.ts||128!==b.ks&&192!==b.ks&&0x100!==b.ks||!b.iv||2>b.iv.length||4 2 | 3 | 4 | 5 | Ionic App 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Ionic ", 3 | "short_name": "Ionic ", 4 | "start_url": "index.html", 5 | "display": "standalone", 6 | "icons": [ 7 | { 8 | "src": "assets/img/appicon.png", 9 | "sizes": "512x512", 10 | "type": "image/png" 11 | } 12 | ], 13 | "background_color": "#387ef5", 14 | "theme_color": "#387ef5" 15 | } 16 | -------------------------------------------------------------------------------- /src/pages/auth/confirmRegistration.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from "@angular/core"; 2 | import {UserRegistrationService} from "../../providers/userRegistration.service"; 3 | import {AlertController, NavController, NavParams} from "ionic-angular"; 4 | import {LoginComponent} from "./login.component"; 5 | import {ResendCodeComponent} from "./resendCode.component"; 6 | import {RegisterComponent} from "./register.component"; 7 | @Component({ 8 | templateUrl: 'confirmRegistration.html', 9 | providers: [UserRegistrationService] 10 | }) 11 | export class ConfirmRegistrationComponent { 12 | confirmationCode: string; 13 | 14 | constructor(public nav: NavController, public userRegistration: UserRegistrationService, public navParam: NavParams, public alertCtrl: AlertController) { 15 | console.log("Entered ConfirmRegistrationComponent"); 16 | console.log("nav param email: " + this.navParam.get("email")) 17 | } 18 | 19 | ionViewLoaded() { 20 | console.log("Entered ionViewDidEnter"); 21 | console.log("email: " + this.navParam.get("email")); 22 | } 23 | 24 | onConfirmRegistration() { 25 | console.log("Confirming registration"); 26 | this.userRegistration.confirmRegistration(this.navParam.get("email"), this.confirmationCode, this); 27 | } 28 | 29 | /** 30 | * callback 31 | * @param message 32 | * @param result 33 | */ 34 | cognitoCallback(message: string, result: any) { 35 | if (message != null) { //error 36 | this.doAlert("Confirmation", message); 37 | } else { //success 38 | console.log("Entered ConfirmRegistrationComponent"); 39 | let email = this.navParam.get("email"); 40 | 41 | if (email != null) 42 | this.nav.push(LoginComponent, { 43 | 'email': email 44 | }); 45 | else 46 | this.nav.push(LoginComponent); 47 | } 48 | } 49 | 50 | navToResendCode() { 51 | this.nav.push(ResendCodeComponent); 52 | } 53 | 54 | navToRegister() { 55 | this.nav.push(RegisterComponent); 56 | } 57 | 58 | navToLogin() { 59 | this.nav.push(LoginComponent); 60 | } 61 | 62 | doAlert(title: string, message: string) { 63 | let alert = this.alertCtrl.create({ 64 | title: title, 65 | subTitle: message, 66 | buttons: ['OK'] 67 | }); 68 | alert.present(); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/pages/auth/confirmRegistration.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | User Confirmation 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Confirmation Code 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/pages/auth/forgotPassword.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | Reset Password 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Email 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/pages/auth/forgotPassword1.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from "@angular/core"; 2 | import {CognitoCallback} from "../../providers/cognito.service"; 3 | import {AlertController, NavController} from "ionic-angular"; 4 | import {ForgotPasswordStep2Component} from "./forgotPassword2.component"; 5 | import {UserLoginService} from "../../providers/userLogin.service"; 6 | import {RegisterComponent} from "./register.component"; 7 | import {LoginComponent} from "./login.component"; 8 | 9 | @Component({ 10 | templateUrl: 'forgotPassword.html' 11 | }) 12 | export class ForgotPasswordStep1Component implements CognitoCallback { 13 | email: string; 14 | 15 | constructor(public nav: NavController, public alertCtrl: AlertController, public userService: UserLoginService) { 16 | } 17 | 18 | onNext() { 19 | this.userService.forgotPassword(this.email, this); 20 | } 21 | 22 | cognitoCallback(message: string, result: any) { 23 | if (message == null && result == null) { //error 24 | this.nav.push(ForgotPasswordStep2Component, {'email': this.email}) 25 | } 26 | } 27 | 28 | navToRegister() { 29 | this.nav.push(RegisterComponent); 30 | } 31 | 32 | navToLogin() { 33 | this.nav.push(LoginComponent); 34 | } 35 | 36 | doAlert(title: string, message: string) { 37 | let alert = this.alertCtrl.create({ 38 | title: title, 39 | subTitle: message, 40 | buttons: ['OK'] 41 | }); 42 | alert.present(); 43 | } 44 | } -------------------------------------------------------------------------------- /src/pages/auth/forgotPassword2.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from "@angular/core"; 2 | import {CognitoCallback} from "../../providers/cognito.service"; 3 | import {AlertController, NavController, NavParams} from "ionic-angular"; 4 | import {UserLoginService} from "../../providers/userLogin.service"; 5 | import {LoginComponent} from "./login.component"; 6 | import {RegisterComponent} from "./register.component"; 7 | @Component({ 8 | templateUrl: 'forgotPasswordStep2.html' 9 | }) 10 | export class ForgotPasswordStep2Component implements CognitoCallback { 11 | 12 | verificationCode: string; 13 | email: string; 14 | password: string; 15 | 16 | constructor(public nav: NavController, public navParam: NavParams, public alertCtrl: AlertController, public userService: UserLoginService) { 17 | this.email = navParam.get("email"); 18 | } 19 | 20 | onNext() { 21 | this.userService.confirmNewPassword(this.email, this.verificationCode, this.password, this); 22 | } 23 | 24 | cognitoCallback(message: string) { 25 | if (message != null) { //error 26 | this.doAlert("Verification Code", message); 27 | } else { //success 28 | this.nav.push(LoginComponent); 29 | } 30 | } 31 | 32 | navToRegister() { 33 | this.nav.push(RegisterComponent); 34 | } 35 | 36 | navToLogin() { 37 | this.nav.push(LoginComponent); 38 | } 39 | 40 | doAlert(title: string, message: string) { 41 | let alert = this.alertCtrl.create({ 42 | title: title, 43 | subTitle: message, 44 | buttons: ['OK'] 45 | }); 46 | alert.present(); 47 | } 48 | } -------------------------------------------------------------------------------- /src/pages/auth/forgotPasswordStep2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | Change Password 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Verification Code 16 | 17 | 18 | 19 | 20 | Password 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/pages/auth/login.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from "@angular/core"; 2 | import {CognitoCallback, LoggedInCallback} from "../../providers/cognito.service"; 3 | import {AlertController, NavController, NavParams} from "ionic-angular"; 4 | import {UserLoginService} from "../../providers/userLogin.service"; 5 | import {EventsService} from "../../providers/events.service"; 6 | import {ControlPanelComponent} from "../controlpanel/controlpanel"; 7 | import {RegisterComponent} from "./register.component"; 8 | import {ForgotPasswordStep1Component} from "./forgotPassword1.component"; 9 | @Component({ 10 | templateUrl: 'login.html' 11 | }) 12 | export class LoginComponent implements CognitoCallback, LoggedInCallback { 13 | email: string; 14 | password: string; 15 | 16 | constructor(public nav: NavController, 17 | public navParam: NavParams, 18 | public alertCtrl: AlertController, 19 | public userService: UserLoginService, 20 | public eventService: EventsService) { 21 | console.log("LoginComponent constructor"); 22 | if (navParam != null && navParam.get("email") != null) 23 | this.email = navParam.get("email"); 24 | 25 | } 26 | 27 | ionViewLoaded() { 28 | console.log("Checking if the user is already authenticated. If so, then redirect to the secure site"); 29 | this.userService.isAuthenticated(this); 30 | } 31 | 32 | signMeIn() { 33 | console.log("in onLogin"); 34 | if (this.email == null || this.password == null) { 35 | this.doAlert("Error", "All fields are required"); 36 | return; 37 | } 38 | this.userService.authenticate(this.email, this.password, this); 39 | } 40 | 41 | cognitoCallback(message: string, result: any) { 42 | if (message != null) { //error 43 | this.doAlert("Error", message); 44 | console.log("result: " + message); 45 | } else { //success 46 | console.log("Redirect to ControlPanelComponent"); 47 | this.nav.setRoot(ControlPanelComponent); 48 | } 49 | } 50 | 51 | isLoggedInCallback(message: string, isLoggedIn: boolean) { 52 | console.log("The user is logged in: " + isLoggedIn); 53 | if (isLoggedIn) { 54 | this.eventService.sendLoggedInEvent(); 55 | this.nav.setRoot(ControlPanelComponent); 56 | } 57 | } 58 | 59 | navToRegister() { 60 | this.nav.push(RegisterComponent); 61 | } 62 | 63 | navToForgotPassword() { 64 | this.nav.push(ForgotPasswordStep1Component); 65 | } 66 | 67 | doAlert(title: string, message: string) { 68 | 69 | let alert = this.alertCtrl.create({ 70 | title: title, 71 | subTitle: message, 72 | buttons: ['OK'] 73 | }); 74 | alert.present(); 75 | } 76 | 77 | } -------------------------------------------------------------------------------- /src/pages/auth/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | Login 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Username 16 | 17 | 18 | 19 | 20 | Password 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/pages/auth/logout.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from "@angular/core"; 2 | import {LoggedInCallback} from "../../providers/cognito.service"; 3 | import {UserLoginService} from "../../providers/userLogin.service"; 4 | import {NavController} from "ionic-angular"; 5 | import {LoginComponent} from "./login.component"; 6 | @Component({ 7 | template: '' 8 | }) 9 | export class LogoutComponent implements LoggedInCallback { 10 | 11 | constructor(public navCtrl: NavController, public userService: UserLoginService) { 12 | this.userService.isAuthenticated(this) 13 | } 14 | 15 | isLoggedInCallback(message: string, isLoggedIn: boolean) { 16 | if (isLoggedIn) { 17 | this.userService.logout(); 18 | } 19 | this.navCtrl.setRoot(LoginComponent) 20 | } 21 | } 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/pages/auth/register.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from "@angular/core"; 2 | import {UserRegistrationService} from "../../providers/userRegistration.service"; 3 | import {CognitoCallback, RegistrationUser} from "../../providers/cognito.service"; 4 | import {AlertController, NavController} from "ionic-angular"; 5 | import {ConfirmRegistrationComponent} from "./confirmRegistration.component"; 6 | import {ResendCodeComponent} from "./resendCode.component"; 7 | import {LoginComponent} from "./login.component"; 8 | 9 | /** 10 | * This component is responsible for displaying and controlling 11 | * the registration of the user. 12 | */ 13 | @Component({ 14 | 15 | templateUrl: 'register.html', 16 | providers: [UserRegistrationService] 17 | }) 18 | export class RegisterComponent implements CognitoCallback { 19 | registrationUser: RegistrationUser; 20 | 21 | constructor(public nav: NavController, 22 | public userRegistration: UserRegistrationService, 23 | public alertCtrl: AlertController) { 24 | this.registrationUser = new RegistrationUser(); 25 | } 26 | 27 | ionViewLoaded() { 28 | 29 | } 30 | 31 | onRegister() { 32 | this.userRegistration.register(this.registrationUser, this); 33 | } 34 | 35 | /** 36 | * CAllback on the user clicking 'register' 37 | * 38 | * The user is taken to a confirmation page where he can enter the confirmation code to finish 39 | * registration 40 | * 41 | */ 42 | cognitoCallback(message: string, result: any) { 43 | if (message != null) { //error 44 | this.doAlert("Registration", message); 45 | } else { //success 46 | console.log("in callback...result: " + result); 47 | this.nav.push(ConfirmRegistrationComponent, { 48 | 'username': result.user.username, 49 | 'email': this.registrationUser.email 50 | }); 51 | } 52 | } 53 | 54 | navToResendCode() { 55 | this.nav.push(ResendCodeComponent); 56 | } 57 | 58 | navToLogin() { 59 | this.nav.push(LoginComponent); 60 | } 61 | 62 | doAlert(title: string, message: string) { 63 | let alert = this.alertCtrl.create({ 64 | title: title, 65 | subTitle: message, 66 | buttons: ['OK'] 67 | }); 68 | alert.present(); 69 | } 70 | 71 | } -------------------------------------------------------------------------------- /src/pages/auth/register.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | Registration 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Username 17 | 18 | 19 | 20 | 21 | Password 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/pages/auth/resendCode.component.ts: -------------------------------------------------------------------------------- 1 | import {Component} from "@angular/core"; 2 | import {UserRegistrationService} from "../../providers/userRegistration.service"; 3 | import {CognitoCallback} from "../../providers/cognito.service"; 4 | import {AlertController, NavController} from "ionic-angular"; 5 | import {ConfirmRegistrationComponent} from "./confirmRegistration.component"; 6 | import {RegisterComponent} from "./register.component"; 7 | import {LoginComponent} from "./login.component"; 8 | @Component({ 9 | templateUrl: 'resendCode.html', 10 | providers: [UserRegistrationService] 11 | }) 12 | export class ResendCodeComponent implements CognitoCallback { 13 | email: string; 14 | 15 | constructor(public nav: NavController, 16 | public registrationService: UserRegistrationService, 17 | public alertCtrl: AlertController) { 18 | } 19 | 20 | resendCode() { 21 | this.registrationService.resendCode(this.email, this); 22 | } 23 | 24 | cognitoCallback(error: any, result: any) { 25 | if (error != null) { 26 | this.doAlert("Resend", "Something went wrong...please try again"); 27 | } else { 28 | this.nav.push(ConfirmRegistrationComponent, { 29 | 'email': this.email 30 | }); 31 | } 32 | } 33 | 34 | navToRegister() { 35 | this.nav.push(RegisterComponent); 36 | } 37 | 38 | navToLogin() { 39 | this.nav.push(LoginComponent); 40 | } 41 | 42 | doAlert(title: string, message: string) { 43 | let alert = this.alertCtrl.create({ 44 | title: title, 45 | subTitle: message, 46 | buttons: ['OK'] 47 | }); 48 | alert.present(); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/pages/auth/resendCode.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | Resend code 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Email 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/pages/controlpanel/controlpanel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | Quick links... 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Welcome to the demo! 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/pages/controlpanel/controlpanel.scss: -------------------------------------------------------------------------------- 1 | .controlpanel { 2 | } 3 | -------------------------------------------------------------------------------- /src/pages/controlpanel/controlpanel.ts: -------------------------------------------------------------------------------- 1 | import {Component} from "@angular/core"; 2 | import {NavController} from "ionic-angular"; 3 | 4 | @Component({ 5 | templateUrl: 'controlpanel.html' 6 | }) 7 | export class ControlPanelComponent { 8 | 9 | 10 | constructor(public nav: NavController) { 11 | console.log("Loaded ControlPanelComponent") 12 | } 13 | 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/providers/aws.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@angular/core"; 2 | import {CognitoUtil} from "./cognito.service"; 3 | import {_IDENTITY_POOL_ID, _MOBILE_ANALYTICS_APP_ID, _REGION, _USER_POOL_ID} from "./properties.service"; 4 | import {UserLoginService} from "./userLogin.service"; 5 | 6 | declare var AWS; 7 | declare var AWSCognito: any; 8 | declare var AMA: any; 9 | 10 | export class Stuff { 11 | public type: string; 12 | public date: string; 13 | } 14 | 15 | @Injectable() 16 | export class AwsUtil { 17 | public static firstLogin: boolean = false; 18 | 19 | constructor(public userLogin: UserLoginService, public cUtil: CognitoUtil) { 20 | 21 | } 22 | 23 | /** 24 | * This is the method that needs to be called in order to init the aws global creds 25 | */ 26 | initAwsService() { 27 | console.log("Running initAwsService()"); 28 | AWSCognito.config.region = _REGION; 29 | AWS.config.region = _REGION; 30 | 31 | var options = { 32 | appId: _MOBILE_ANALYTICS_APP_ID, //Amazon Mobile Analytics App ID 33 | }; 34 | 35 | var mobileAnalyticsClient = new AMA.Manager(options); 36 | mobileAnalyticsClient.submitEvents(); 37 | 38 | // First check if the user is authenticated already 39 | let mythis = this; 40 | this.userLogin.isAuthenticated({ 41 | isLoggedInCallback(message: string, loggedIn: boolean) { 42 | mythis.setupAWS(loggedIn); 43 | } 44 | }); 45 | } 46 | 47 | 48 | /** 49 | * Sets up the AWS global params 50 | * 51 | * @param isLoggedIn 52 | * @param callback 53 | */ 54 | setupAWS(isLoggedIn: boolean): void { 55 | console.log("in setupAWS()"); 56 | let mythis = this; 57 | if (isLoggedIn) { 58 | console.log("User is logged in"); 59 | this.cUtil.getIdToken({ 60 | callback() { 61 | }, 62 | callbackWithParam(idToken: any) { 63 | console.log("idJWT Token: " + idToken); 64 | mythis.addCognitoCredentials(idToken); 65 | } 66 | }); 67 | console.log("Retrieving the id token"); 68 | } 69 | else { 70 | console.log("User is not logged in. "); 71 | AWSCognito.config.credentials = new AWS.CognitoIdentityCredentials({ 72 | IdentityPoolId: _IDENTITY_POOL_ID 73 | }); 74 | } 75 | } 76 | 77 | addCognitoCredentials(idTokenJwt: string): void { 78 | console.log("in addCognitoCredentials"); 79 | let params = this.getCognitoParametersForIdConsolidation(idTokenJwt); 80 | 81 | AWS.config.credentials = new AWS.CognitoIdentityCredentials(params); 82 | AWSCognito.config.credentials = new AWS.CognitoIdentityCredentials(params); 83 | 84 | console.log("Getting the credentials class"); 85 | // AWS.config.credentials.get(function (err) { 86 | // if (!err) { 87 | // 88 | // } 89 | // }); 90 | } 91 | 92 | getCognitoParametersForIdConsolidation(idTokenJwt: string): {} { 93 | console.log("enter getCognitoParametersForIdConsolidation()"); 94 | let url = 'cognito-idp.' + _REGION.toLowerCase() + '.amazonaws.com/' + _USER_POOL_ID; 95 | console.log("ur: " + url); 96 | let logins: Array = []; 97 | logins[url] = idTokenJwt; 98 | let params = { 99 | IdentityPoolId: _IDENTITY_POOL_ID, /* required */ 100 | Logins: logins 101 | }; 102 | 103 | return params; 104 | } 105 | 106 | } 107 | 108 | -------------------------------------------------------------------------------- /src/providers/cognito.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@angular/core"; 2 | import {_POOL_DATA} from "./properties.service"; 3 | 4 | declare let AWS: any; 5 | declare let AWSCognito: any; 6 | 7 | export class RegistrationUser { 8 | name: string; 9 | email: string; 10 | password: string; 11 | } 12 | 13 | export interface CognitoCallback { 14 | cognitoCallback(message: string, result: any): void; 15 | } 16 | 17 | export interface LoggedInCallback { 18 | isLoggedInCallback(message: string, loggedIn: boolean): void; 19 | } 20 | 21 | export interface Callback { 22 | callback(): void; 23 | callbackWithParam(result: any): void; 24 | } 25 | 26 | @Injectable() 27 | export class CognitoUtil { 28 | 29 | constructor() { 30 | console.log("CognitoUtil constructor"); 31 | } 32 | 33 | getUserPool() { 34 | return new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool(_POOL_DATA); 35 | } 36 | 37 | getCurrentUser() { 38 | return this.getUserPool().getCurrentUser(); 39 | } 40 | 41 | 42 | getCognitoIdentity(): string { 43 | return AWS.config.credentials.identityId; 44 | } 45 | 46 | getAccessToken(callback: Callback): void { 47 | if (callback == null) { 48 | throw("callback in getAccessToken is null...returning"); 49 | } 50 | this.getCurrentUser().getSession(function (err, session) { 51 | if (err) { 52 | console.log("Can't set the credentials:" + err); 53 | callback.callbackWithParam(null); 54 | } 55 | 56 | else { 57 | if (session.isValid()) { 58 | callback.callbackWithParam(session.getAccessToken().getJwtToken()); 59 | } 60 | } 61 | }); 62 | } 63 | 64 | getIdToken(callback: Callback): void { 65 | if (callback == null) { 66 | throw("callback in getIdToken is null...returning"); 67 | } 68 | this.getCurrentUser().getSession(function (err, session) { 69 | if (err) { 70 | console.log("Can't set the credentials:" + err); 71 | callback.callbackWithParam(null); 72 | } 73 | else { 74 | if (session.isValid()) { 75 | callback.callbackWithParam(session.getIdToken().getJwtToken()); 76 | } else { 77 | console.log("Got the id token, but the session isn't valid"); 78 | } 79 | } 80 | }); 81 | } 82 | 83 | getRefreshToken(callback: Callback): void { 84 | if (callback == null) { 85 | throw("callback in getRefreshToken is null...returning"); 86 | } 87 | this.getCurrentUser().getSession(function (err, session) { 88 | if (err) { 89 | console.log("Can't set the credentials:" + err); 90 | callback.callbackWithParam(null); 91 | } 92 | 93 | else { 94 | if (session.isValid()) { 95 | callback.callbackWithParam(session.getRefreshToken()); 96 | } 97 | } 98 | }); 99 | } 100 | } 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /src/providers/events.service.ts: -------------------------------------------------------------------------------- 1 | import {Events} from "ionic-angular/index"; 2 | import {Injectable} from "@angular/core"; 3 | 4 | export const _USER_LOGOUT_EVENT = 'user:logout'; 5 | export const _USER_LOGIN_EVENT = 'user:login'; 6 | 7 | @Injectable() 8 | export class EventsService { 9 | 10 | constructor(public events: Events) { 11 | 12 | } 13 | 14 | sendLoggedInEvent() { 15 | console.log("Publishing login event"); 16 | this.events.publish(_USER_LOGIN_EVENT); 17 | } 18 | 19 | sendLogoutEvent() { 20 | console.log("Publishing logout event"); 21 | this.events.publish(_USER_LOGOUT_EVENT); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/providers/properties.service.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Vladimir Budilov on 8/13/16. 3 | */ 4 | 5 | export let _REGION = "us-east-1"; 6 | 7 | export let _IDENTITY_POOL_ID = "us-east-1:688daf8f-a234-423e-9222-4d489c796834"; 8 | export let _USER_POOL_ID = "us-east-1_bybDCnVM9"; 9 | export let _CLIENT_ID = "3hl0eo4321kv7i3i2amqa8k8jf"; 10 | export let _MOBILE_ANALYTICS_APP_ID = "8ed115bcfac94dfa8e364aa5ef201849"; 11 | 12 | export let _POOL_DATA = { 13 | UserPoolId: _USER_POOL_ID, 14 | ClientId: _CLIENT_ID 15 | }; 16 | -------------------------------------------------------------------------------- /src/providers/userLogin.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@angular/core"; 2 | import {CognitoCallback, CognitoUtil, LoggedInCallback} from "./cognito.service"; 3 | import {EventsService} from "./events.service"; 4 | declare let AWS: any; 5 | declare let AWSCognito: any; 6 | 7 | @Injectable() 8 | export class UserLoginService { 9 | 10 | constructor(public cUtil: CognitoUtil, public eventService: EventsService) { 11 | console.log("eventservice1: " + eventService); 12 | } 13 | 14 | authenticate(username: string, password: string, callback: CognitoCallback) { 15 | let mythis = this; 16 | 17 | // Need to provide placeholder keys unless unauthorised user access is enabled for user pool 18 | AWSCognito.config.update({accessKeyId: 'anything', secretAccessKey: 'anything'}) 19 | 20 | let authenticationData = { 21 | Username: username, 22 | Password: password, 23 | }; 24 | let authenticationDetails = new AWSCognito.CognitoIdentityServiceProvider.AuthenticationDetails(authenticationData); 25 | 26 | let userData = { 27 | Username: username, 28 | Pool: this.cUtil.getUserPool() 29 | }; 30 | 31 | console.log("Authenticating the user"); 32 | let cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData); 33 | cognitoUser.authenticateUser(authenticationDetails, { 34 | onSuccess: function (result) { 35 | callback.cognitoCallback(null, result); 36 | mythis.eventService.sendLoggedInEvent(); 37 | }, 38 | onFailure: function (err) { 39 | callback.cognitoCallback(err.message, null); 40 | }, 41 | }); 42 | } 43 | 44 | forgotPassword(username: string, callback: CognitoCallback) { 45 | let userData = { 46 | Username: username, 47 | Pool: this.cUtil.getUserPool() 48 | }; 49 | 50 | let cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData); 51 | 52 | cognitoUser.forgotPassword({ 53 | onSuccess: function (result) { 54 | 55 | }, 56 | onFailure: function (err) { 57 | callback.cognitoCallback(err.message, null); 58 | }, 59 | inputVerificationCode() { 60 | callback.cognitoCallback(null, null); 61 | } 62 | }); 63 | } 64 | 65 | confirmNewPassword(email: string, verificationCode: string, password: string, callback: CognitoCallback) { 66 | let userData = { 67 | Username: email, 68 | Pool: this.cUtil.getUserPool() 69 | }; 70 | 71 | let cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData); 72 | 73 | cognitoUser.confirmPassword(verificationCode, password, { 74 | onSuccess: function (result) { 75 | callback.cognitoCallback(null, result); 76 | }, 77 | onFailure: function (err) { 78 | callback.cognitoCallback(err.message, null); 79 | } 80 | }); 81 | } 82 | 83 | logout() { 84 | console.log("Logging out"); 85 | this.cUtil.getCurrentUser().signOut(); 86 | this.eventService.sendLogoutEvent(); 87 | } 88 | 89 | isAuthenticated(callback: LoggedInCallback) { 90 | if (callback == null) 91 | throw("Callback in isAuthenticated() cannot be null"); 92 | 93 | console.log("Getting the current user"); 94 | let cognitoUser = this.cUtil.getCurrentUser(); 95 | 96 | if (cognitoUser != null) { 97 | cognitoUser.getSession(function (err, session) { 98 | if (err) { 99 | console.log("Couldn't get the session: " + err, err.stack); 100 | callback.isLoggedInCallback(err, false); 101 | } 102 | else { 103 | console.log("Session is valid: " + session.isValid()); 104 | callback.isLoggedInCallback(err, session.isValid()); 105 | } 106 | }); 107 | } else { 108 | callback.isLoggedInCallback("Can't retrieve the CurrentUser", false); 109 | } 110 | } 111 | } -------------------------------------------------------------------------------- /src/providers/userParameters.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@angular/core"; 2 | import {Callback, CognitoUtil} from "./cognito.service"; 3 | @Injectable() 4 | export class UserParametersService { 5 | 6 | constructor(public cUtil: CognitoUtil) { 7 | 8 | } 9 | 10 | getParameters(callback: Callback) { 11 | let cognitoUser = this.cUtil.getCurrentUser(); 12 | 13 | if (cognitoUser != null) { 14 | cognitoUser.getSession(function (err, session) { 15 | if (err) 16 | console.log("Couldn't retrieve the user"); 17 | else { 18 | cognitoUser.getUserAttributes(function (err, result) { 19 | if (err) { 20 | console.log("in getParameters: " + err); 21 | } else { 22 | callback.callbackWithParam(result); 23 | } 24 | }); 25 | } 26 | 27 | }); 28 | } else { 29 | callback.callbackWithParam(null); 30 | } 31 | 32 | 33 | } 34 | 35 | getParameter(name: string, callback: Callback) { 36 | 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /src/providers/userRegistration.service.ts: -------------------------------------------------------------------------------- 1 | import {CognitoCallback, CognitoUtil, RegistrationUser} from "./cognito.service"; 2 | import {Injectable} from "@angular/core"; 3 | 4 | declare let AWS: any; 5 | declare let AWSCognito: any; 6 | 7 | @Injectable() 8 | export class UserRegistrationService { 9 | constructor(public cUtil: CognitoUtil) { 10 | } 11 | 12 | register(user: RegistrationUser, callback: CognitoCallback): void { 13 | console.log("user: " + user); 14 | 15 | let attributeList = []; 16 | 17 | let dataEmail = { 18 | Name: 'email', 19 | Value: user.email 20 | }; 21 | let dataNickname = { 22 | Name: 'nickname', 23 | Value: user.name 24 | }; 25 | attributeList.push(new AWSCognito.CognitoIdentityServiceProvider.CognitoUserAttribute(dataEmail)); 26 | attributeList.push(new AWSCognito.CognitoIdentityServiceProvider.CognitoUserAttribute(dataNickname)); 27 | 28 | this.cUtil.getUserPool().signUp(user.email, user.password, attributeList, null, function (err, result) { 29 | if (err) { 30 | callback.cognitoCallback(err.message, null); 31 | } else { 32 | console.log("registered user: " + result); 33 | callback.cognitoCallback(null, result); 34 | } 35 | }); 36 | 37 | } 38 | 39 | confirmRegistration(username: string, confirmationCode: string, callback: CognitoCallback): void { 40 | 41 | let userData = { 42 | Username: username, 43 | Pool: this.cUtil.getUserPool() 44 | }; 45 | 46 | let cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData); 47 | 48 | cognitoUser.confirmRegistration(confirmationCode, true, function (err, result) { 49 | if (err) { 50 | callback.cognitoCallback(err.message, null); 51 | } else { 52 | callback.cognitoCallback(null, result); 53 | } 54 | }); 55 | } 56 | 57 | resendCode(username: string, callback: CognitoCallback): void { 58 | let userData = { 59 | Username: username, 60 | Pool: this.cUtil.getUserPool() 61 | }; 62 | 63 | let cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData); 64 | 65 | cognitoUser.resendConfirmationCode(function (err, result) { 66 | if (err) { 67 | callback.cognitoCallback(err.message, null); 68 | } else { 69 | callback.cognitoCallback(null, result); 70 | } 71 | }); 72 | } 73 | 74 | } -------------------------------------------------------------------------------- /src/service-worker.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vbudilov/ionic-app-with-aws-cognito/669938b9e044e1df4d12583b7d23a06209abe22a/src/service-worker.js -------------------------------------------------------------------------------- /src/theme/global.scss: -------------------------------------------------------------------------------- 1 | // http://ionicframework.com/docs/v2/theming/ 2 | 3 | // Global CSS 4 | // -------------------------------------------------- 5 | // Put CSS rules here that you want to apply globally. 6 | // 7 | // To declare rules for a specific mode, create a child rule 8 | // for the .md, .ios, or .wp mode classes. The mode class is 9 | // automatically applied to the element in the app. 10 | // 11 | // App Shared Sass variables belong in app.variables.scss. 12 | -------------------------------------------------------------------------------- /src/theme/variables.scss: -------------------------------------------------------------------------------- 1 | // Ionic Variables and Theming. For more info, please see: 2 | // http://ionicframework.com/docs/v2/theming/ 3 | @import "ionic.globals"; 4 | 5 | // Shared Variables 6 | // -------------------------------------------------- 7 | // To customize the look and feel of this app, you can override 8 | // the Sass variables found in Ionic's source scss files. 9 | // To view all the possible Ionic variables, see: 10 | // http://ionicframework.com/docs/v2/theming/overriding-ionic-variables/ 11 | 12 | $text-color: #000; 13 | $background-color: #fff; 14 | 15 | // Named Color Variables 16 | // -------------------------------------------------- 17 | // Named colors makes it easy to reuse colors on various components. 18 | // It's highly recommended to change the default colors 19 | // to match your app's branding. Ionic uses a Sass map of 20 | // colors so you can add, rename and remove colors as needed. 21 | // The "primary" color is the only required color in the map. 22 | 23 | $colors: ( 24 | primary: #387ef5, 25 | secondary: #32db64, 26 | danger: #f53d3d, 27 | light: #f4f4f4, 28 | dark: #222, 29 | favorite: #69BB7B 30 | ); 31 | 32 | // App Theme 33 | // -------------------------------------------------- 34 | // Ionic apps can have different themes applied, which can 35 | // then be future customized. This import comes last 36 | // so that the above variables are used and Ionic's 37 | // default are overridden. 38 | 39 | @import "ionic.theme.default"; 40 | 41 | // Ionicons 42 | // -------------------------------------------------- 43 | // The premium icon font for Ionic. For more info, please see: 44 | // http://ionicframework.com/docs/v2/ionicons/ 45 | 46 | $ionicons-font-path: "../assets/fonts"; 47 | @import "ionicons"; 48 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "declaration": false, 5 | "emitDecoratorMetadata": true, 6 | "experimentalDecorators": true, 7 | "lib": [ 8 | "dom", 9 | "es2015" 10 | ], 11 | "module": "es2015", 12 | "moduleResolution": "node", 13 | "sourceMap": true, 14 | "target": "es5" 15 | }, 16 | "include": [ 17 | "src/**/*.ts" 18 | ], 19 | "exclude": [ 20 | "node_modules" 21 | ], 22 | "compileOnSave": false, 23 | "atom": { 24 | "rewriteTsconfig": false 25 | } 26 | } -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-duplicate-variable": true, 4 | "no-unused-variable": [ 5 | true 6 | ] 7 | }, 8 | "rulesDirectory": [ 9 | "node_modules/tslint-eslint-rules/dist/rules" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /www/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | Ionic App 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | --------------------------------------------------------------------------------