├── .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 |
25 |
26 |
27 |
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 |
--------------------------------------------------------------------------------