├── www
├── .gitkeep
├── service-worker.js
└── manifest.json
├── src
├── pages
│ ├── tasks
│ │ ├── tasks.scss
│ │ ├── tasks.html
│ │ └── tasks.ts
│ ├── confirm
│ │ ├── confirm.scss
│ │ ├── confirm.html
│ │ └── confirm.ts
│ ├── about
│ │ ├── about.scss
│ │ ├── about.ts
│ │ └── about.html
│ ├── tasks-create
│ │ ├── tasks-create.scss
│ │ ├── tasks-create.ts
│ │ └── tasks-create.html
│ ├── login
│ │ ├── login.scss
│ │ ├── login.html
│ │ └── login.ts
│ ├── signup
│ │ ├── signup.scss
│ │ ├── signup.html
│ │ └── signup.ts
│ ├── tabs
│ │ ├── tabs.html
│ │ └── tabs.ts
│ ├── account
│ │ ├── account.scss
│ │ ├── account.html
│ │ └── account.ts
│ └── settings
│ │ ├── settings.html
│ │ └── settings.ts
├── app
│ ├── app.html
│ ├── app.config.ts
│ ├── app.component.ts
│ └── app.module.ts
├── assets
│ ├── ionic-aws-logo.png
│ └── amazon-cognito-identity.min.js
├── providers
│ ├── providers.ts
│ ├── aws.dynamodb.ts
│ ├── aws.cognito.ts
│ └── user.ts
└── index.html
├── patch.package.json
├── mobile-hub-project.zip
├── README.md
└── cors-policy.xml
/www/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/pages/tasks/tasks.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/pages/confirm/confirm.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/pages/about/about.scss:
--------------------------------------------------------------------------------
1 | page-about {
2 | }
3 |
--------------------------------------------------------------------------------
/src/app/app.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/patch.package.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "@ionic-native/camera": "3.13.0"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/mobile-hub-project.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic2-starter-aws/HEAD/mobile-hub-project.zip
--------------------------------------------------------------------------------
/src/assets/ionic-aws-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ionic-team/ionic2-starter-aws/HEAD/src/assets/ionic-aws-logo.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### :point_right: This starter repo has moved to the [ionic-team/starters](https://github.com/ionic-team/starters/tree/master/ionic-angular/official/aws) repo! :point_left:
2 |
--------------------------------------------------------------------------------
/src/pages/tasks-create/tasks-create.scss:
--------------------------------------------------------------------------------
1 | page-tasks-create {
2 | .custom-item {
3 | flex-direction: column;
4 |
5 | textarea {
6 | margin: 0;
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/pages/login/login.scss:
--------------------------------------------------------------------------------
1 | page-login {
2 | .logo {
3 | padding: 20px 0px 0px 0px;
4 | text-align: center;
5 |
6 | img {
7 | max-width: 150px;
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/pages/signup/signup.scss:
--------------------------------------------------------------------------------
1 | page-signup {
2 | .logo {
3 | padding: 20px 0px 0px 0px;
4 | text-align: center;
5 |
6 | img {
7 | max-width: 150px;
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/pages/tabs/tabs.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/providers/providers.ts:
--------------------------------------------------------------------------------
1 | import { Cognito } from './aws.cognito';
2 | import { DynamoDB } from './aws.dynamodb';
3 | import { User } from './user';
4 |
5 | export {
6 | Cognito,
7 | DynamoDB,
8 | User
9 | };
10 |
--------------------------------------------------------------------------------
/www/service-worker.js:
--------------------------------------------------------------------------------
1 | self.addEventListener('activate', function (event) {
2 |
3 | });
4 |
5 | self.addEventListener('fetch', function (event) {
6 |
7 | });
8 |
9 | self.addEventListener('push', function (event) {
10 |
11 | });
--------------------------------------------------------------------------------
/src/pages/about/about.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'page-about',
5 | templateUrl: 'about.html'
6 | })
7 | export class AboutPage {
8 |
9 | constructor() {
10 |
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/www/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "My Ionic App",
3 | "short_name": "My Ionic App",
4 | "start_url": "index.html",
5 | "display": "standalone",
6 | "icons": [{
7 | "src": "icon.png",
8 | "sizes": "512x512",
9 | "type": "image/png"
10 | }]
11 | }
--------------------------------------------------------------------------------
/src/pages/tabs/tabs.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | import { SettingsPage } from '../settings/settings';
4 | import { TasksPage } from '../tasks/tasks';
5 |
6 | @Component({
7 | templateUrl: 'tabs.html'
8 | })
9 | export class TabsPage {
10 |
11 | tab1Root = TasksPage;
12 | tab2Root = SettingsPage;
13 |
14 | constructor() {
15 |
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/providers/aws.dynamodb.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 |
3 | declare var AWS: any;
4 |
5 | @Injectable()
6 | export class DynamoDB {
7 |
8 | private documentClient: any;
9 |
10 | constructor() {
11 | this.documentClient = new AWS.DynamoDB.DocumentClient();
12 | }
13 |
14 | getDocumentClient() {
15 | return this.documentClient;
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/pages/account/account.scss:
--------------------------------------------------------------------------------
1 | page-account {
2 | .avatar-input {
3 | display: none;
4 | }
5 |
6 | .avatar {
7 | display: block;
8 | width: 150px;
9 | height: 150px;
10 | border-radius: 50%;
11 | background-repeat: no-repeat;
12 | background-position: center center;
13 | background-size: cover;
14 |
15 | margin: 0 auto;
16 | border: 5px solid #f1f1f1;
17 | box-shadow: 0 0 5px #999;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/pages/about/about.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | About
5 |
6 |
7 |
8 |
9 |
10 |
11 | This is a starter project that leverages AWS Mobile Hub services to power the app. The
12 | following services are utilized:
13 |
14 |
15 | - Cognito (Authentication)
16 | - DynamoDB (Data Storage)
17 | - S3 (File Storage)
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/pages/settings/settings.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Settings
5 |
6 |
7 |
8 |
9 |
10 |
11 |
14 |
17 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/cors-policy.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | *
5 | HEAD
6 | PUT
7 | GET
8 | 3000
9 | x-amz-server-side-encryption
10 | x-amz-request-id
11 | x-amz-id-2
12 | *
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/pages/settings/settings.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { App } from 'ionic-angular';
3 | import { LoginPage } from '../login/login';
4 | import { AboutPage } from '../about/about';
5 | import { AccountPage } from '../account/account';
6 |
7 | import { User } from '../../providers/providers';
8 |
9 | @Component({
10 | templateUrl: 'settings.html'
11 | })
12 | export class SettingsPage {
13 |
14 | public aboutPage = AboutPage;
15 | public accountPage = AccountPage;
16 |
17 | constructor(public user: User, public app: App) {
18 | }
19 |
20 | logout() {
21 | this.user.logout();
22 | this.app.getRootNav().setRoot(LoginPage);
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/pages/confirm/confirm.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Please enter the confirmation code sent to your email to verify your account:
4 |
5 |
23 |
24 |
--------------------------------------------------------------------------------
/src/pages/confirm/confirm.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | import { NavController, NavParams } from 'ionic-angular';
4 |
5 | import { LoginPage } from '../login/login';
6 | import { User } from '../../providers/user';
7 |
8 | @Component({
9 | selector: 'page-confirm',
10 | templateUrl: 'confirm.html'
11 | })
12 | export class ConfirmPage {
13 |
14 | public code: string;
15 | public username: string;
16 |
17 | constructor(public navCtrl: NavController, public navParams: NavParams, public user: User) {
18 | this.username = navParams.get('username');
19 | }
20 |
21 | confirm() {
22 | this.user.confirmRegistration(this.username, this.code).then(() => {
23 | this.navCtrl.push(LoginPage);
24 | });
25 | }
26 |
27 | resendCode() {
28 | this.user.resendRegistrationCode(this.username);
29 | }
30 |
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/pages/account/account.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Account
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | username {{ user.getUser().getUsername() }}
24 |
25 |
26 | {{ attr.getName() }} {{ attr.getValue() }}
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/pages/login/login.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |

4 |
5 |
28 |
29 |
--------------------------------------------------------------------------------
/src/pages/tasks-create/tasks-create.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { NavController, NavParams, ViewController, Platform } from 'ionic-angular';
3 |
4 | @Component({
5 | selector: 'page-tasks-create',
6 | templateUrl: 'tasks-create.html'
7 | })
8 | export class TasksCreatePage {
9 |
10 | isReadyToSave: boolean;
11 |
12 | item: any;
13 |
14 | isAndroid: boolean;
15 |
16 |
17 | constructor(public navCtrl: NavController,
18 | public navParams: NavParams,
19 | public viewCtrl: ViewController,
20 | public platform: Platform) {
21 | this.isAndroid = platform.is('android');
22 | this.item = {
23 | 'taskId': navParams.get('id'),
24 | 'category': 'Todo'
25 | };
26 | this.isReadyToSave = true;
27 | }
28 |
29 | ionViewDidLoad() {
30 |
31 | }
32 |
33 | cancel() {
34 | this.viewCtrl.dismiss();
35 | }
36 |
37 | done() {
38 | this.viewCtrl.dismiss(this.item);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/app/app.config.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 |
3 | declare var AWS: any;
4 | declare const aws_mobile_analytics_app_id;
5 | declare const aws_cognito_region;
6 | declare const aws_cognito_identity_pool_id;
7 | declare const aws_user_pools_id;
8 | declare const aws_user_pools_web_client_id;
9 | declare const aws_user_files_s3_bucket;
10 |
11 | @Injectable()
12 | export class AwsConfig {
13 | public load() {
14 |
15 | // Expects global const values defined by aws-config.js
16 | const cfg = {
17 | "aws_mobile_analytics_app_id": aws_mobile_analytics_app_id,
18 | "aws_cognito_region": aws_cognito_region,
19 | "aws_cognito_identity_pool_id": aws_cognito_identity_pool_id,
20 | "aws_user_pools_id": aws_user_pools_id,
21 | "aws_user_pools_web_client_id": aws_user_pools_web_client_id,
22 | "aws_user_files_s3_bucket": aws_user_files_s3_bucket
23 | };
24 |
25 | AWS.config.customUserAgent = AWS.config.customUserAgent + ' Ionic';
26 |
27 | return cfg;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/pages/tasks/tasks.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Tasks
5 |
6 |
7 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
21 |
22 |
23 |
24 |
25 |
26 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/src/pages/signup/signup.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |

4 |
5 |
34 |
35 |
--------------------------------------------------------------------------------
/src/pages/tasks-create/tasks-create.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | New Task
5 |
6 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Category
22 |
23 | Todo
24 | Errand
25 |
26 |
27 |
28 |
29 | Task Description
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { Config, Platform } from 'ionic-angular';
3 | import { StatusBar } from '@ionic-native/status-bar';
4 | import { SplashScreen } from '@ionic-native/splash-screen';
5 |
6 | import { TabsPage } from '../pages/tabs/tabs';
7 | import { LoginPage } from '../pages/login/login';
8 |
9 | import { User } from '../providers/user';
10 |
11 |
12 | @Component({
13 | templateUrl: 'app.html'
14 | })
15 | export class MyApp {
16 | rootPage:any = null;
17 |
18 | constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen, user: User, public config: Config) {
19 | let globalActions = function() {
20 | // Okay, so the platform is ready and our plugins are available.
21 | // Here you can do any higher level native things you might need.
22 | statusBar.styleDefault();
23 | splashScreen.hide();
24 | };
25 |
26 | platform.ready().then(() => {
27 | user.isAuthenticated().then(() => {
28 | console.log('you are authenticated!');
29 | this.rootPage = TabsPage;
30 | globalActions();
31 | }).catch(() => {
32 | console.log('you are not authenticated..');
33 | this.rootPage = LoginPage;
34 | globalActions();
35 | });
36 | });
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/pages/signup/signup.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | import { NavController, LoadingController } from 'ionic-angular';
4 |
5 | import { LoginPage } from '../login/login';
6 | import { ConfirmPage } from '../confirm/confirm';
7 |
8 | import { User } from '../../providers/user';
9 |
10 | export class UserDetails {
11 | username: string;
12 | email: string;
13 | password: string;
14 | }
15 |
16 | @Component({
17 | selector: 'page-signup',
18 | templateUrl: 'signup.html'
19 | })
20 | export class SignupPage {
21 |
22 | public userDetails: UserDetails;
23 |
24 | error: any;
25 |
26 | constructor(public navCtrl: NavController,
27 | public user: User,
28 | public loadingCtrl: LoadingController) {
29 | this.userDetails = new UserDetails();
30 | }
31 |
32 | signup() {
33 |
34 | let loading = this.loadingCtrl.create({
35 | content: 'Please wait...'
36 | });
37 | loading.present();
38 |
39 | let details = this.userDetails;
40 | this.error = null;
41 | console.log('register');
42 | this.user.register(details.username, details.password, {'email': details.email}).then((user) => {
43 | loading.dismiss();
44 | this.navCtrl.push(ConfirmPage, { username: details.username });
45 | }).catch((err) => {
46 | loading.dismiss();
47 | this.error = err;
48 | });
49 | }
50 |
51 | login() {
52 | this.navCtrl.push(LoginPage);
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/src/pages/login/login.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | import { NavController, LoadingController } from 'ionic-angular';
4 |
5 | import { TabsPage } from '../tabs/tabs';
6 | import { SignupPage } from '../signup/signup';
7 | import { ConfirmPage } from '../confirm/confirm';
8 |
9 | import { User } from '../../providers/providers';
10 |
11 | export class LoginDetails {
12 | username: string;
13 | password: string;
14 | }
15 |
16 | @Component({
17 | selector: 'page-login',
18 | templateUrl: 'login.html'
19 | })
20 | export class LoginPage {
21 |
22 | public loginDetails: LoginDetails;
23 |
24 | constructor(public navCtrl: NavController,
25 | public user: User,
26 | public loadingCtrl: LoadingController) {
27 | this.loginDetails = new LoginDetails();
28 | }
29 |
30 | login() {
31 | let loading = this.loadingCtrl.create({
32 | content: 'Please wait...'
33 | });
34 | loading.present();
35 |
36 | let details = this.loginDetails;
37 | console.log('login..');
38 | this.user.login(details.username, details.password).then((result) => {
39 | console.log('result:', result);
40 | loading.dismiss();
41 | this.navCtrl.setRoot(TabsPage);
42 | }).catch((err) => {
43 | if (err.message === "User is not confirmed.") {
44 | loading.dismiss();
45 | this.navCtrl.push(ConfirmPage, { 'username': details.username });
46 | }
47 | console.log('errrror', err);
48 | loading.dismiss();
49 | });
50 | }
51 |
52 | signup() {
53 | this.navCtrl.push(SignupPage);
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/src/providers/aws.cognito.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Config } from 'ionic-angular';
3 |
4 | declare var AWS: any;
5 | declare var AWSCognito: any;
6 |
7 | declare const aws_cognito_region;
8 | declare const aws_cognito_identity_pool_id;
9 | declare const aws_user_pools_id;
10 | declare const aws_user_pools_web_client_id;
11 |
12 | @Injectable()
13 | export class Cognito {
14 |
15 | constructor(public config: Config) {
16 | AWSCognito.config.region = aws_cognito_region;
17 | AWSCognito.config.credentials = new AWS.CognitoIdentityCredentials({
18 | IdentityPoolId: aws_cognito_identity_pool_id
19 | });
20 | AWSCognito.config.update({customUserAgent: AWS.config.customUserAgent});
21 | }
22 |
23 | getUserPool() {
24 | return new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool({
25 | "UserPoolId": aws_user_pools_id,
26 | "ClientId": aws_user_pools_web_client_id
27 | });
28 | }
29 |
30 | getCurrentUser() {
31 | return this.getUserPool().getCurrentUser();
32 | }
33 |
34 | makeAuthDetails(username, password) {
35 | return new AWSCognito.CognitoIdentityServiceProvider.AuthenticationDetails({
36 | 'Username': username,
37 | 'Password': password
38 | });
39 | }
40 |
41 | makeAttribute(name, value) {
42 | return new AWSCognito.CognitoIdentityServiceProvider.CognitoUserAttribute({
43 | 'Name': name,
44 | 'Value': value
45 | });
46 | }
47 |
48 | makeUser(username) {
49 | return new AWSCognito.CognitoIdentityServiceProvider.CognitoUser({
50 | 'Username': username,
51 | 'Pool': this.getUserPool()
52 | });
53 | }
54 |
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Ionic App
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule, ErrorHandler } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 | import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
4 |
5 | import { Camera } from '@ionic-native/camera';
6 |
7 | import { MyApp } from './app.component';
8 | import { LoginPage } from '../pages/login/login';
9 | import { SignupPage } from '../pages/signup/signup';
10 | import { ConfirmPage } from '../pages/confirm/confirm';
11 | import { SettingsPage } from '../pages/settings/settings';
12 | import { AboutPage } from '../pages/about/about';
13 | import { AccountPage } from '../pages/account/account';
14 | import { TabsPage } from '../pages/tabs/tabs';
15 | import { TasksPage } from '../pages/tasks/tasks';
16 | import { TasksCreatePage } from '../pages/tasks-create/tasks-create';
17 |
18 | import { StatusBar } from '@ionic-native/status-bar';
19 | import { SplashScreen } from '@ionic-native/splash-screen';
20 |
21 | import { User } from '../providers/user';
22 | import { Cognito } from '../providers/aws.cognito';
23 | import { DynamoDB } from '../providers/aws.dynamodb';
24 |
25 |
26 | @NgModule({
27 | declarations: [
28 | MyApp,
29 | LoginPage,
30 | SignupPage,
31 | ConfirmPage,
32 | SettingsPage,
33 | AboutPage,
34 | AccountPage,
35 | TabsPage,
36 | TasksPage,
37 | TasksCreatePage
38 | ],
39 | imports: [
40 | BrowserModule,
41 | IonicModule.forRoot(MyApp)
42 | ],
43 | bootstrap: [IonicApp],
44 | entryComponents: [
45 | MyApp,
46 | LoginPage,
47 | SignupPage,
48 | ConfirmPage,
49 | SettingsPage,
50 | AboutPage,
51 | AccountPage,
52 | TabsPage,
53 | TasksPage,
54 | TasksCreatePage
55 | ],
56 | providers: [
57 | StatusBar,
58 | SplashScreen,
59 | {provide: ErrorHandler, useClass: IonicErrorHandler},
60 | Camera,
61 | User,
62 | Cognito,
63 | DynamoDB
64 | ]
65 | })
66 | export class AppModule {}
67 |
68 | declare var AWS;
69 | AWS.config.customUserAgent = AWS.config.customUserAgent + ' Ionic';
70 |
--------------------------------------------------------------------------------
/src/pages/tasks/tasks.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | import { NavController, ModalController } from 'ionic-angular';
4 | import { TasksCreatePage } from '../tasks-create/tasks-create';
5 |
6 | import { DynamoDB, User } from '../../providers/providers';
7 |
8 | declare var AWS: any;
9 |
10 | @Component({
11 | selector: 'page-tasks',
12 | templateUrl: 'tasks.html'
13 | })
14 | export class TasksPage {
15 |
16 | public items: any;
17 | public refresher: any;
18 | private taskTable: string = 'ionic-mobile-hub-tasks';
19 |
20 | constructor(public navCtrl: NavController,
21 | public modalCtrl: ModalController,
22 | public user: User,
23 | public db: DynamoDB) {
24 |
25 | this.refreshTasks();
26 | }
27 |
28 | refreshData(refresher) {
29 | this.refresher = refresher;
30 | this.refreshTasks()
31 | }
32 |
33 | refreshTasks() {
34 | this.db.getDocumentClient().query({
35 | 'TableName': this.taskTable,
36 | 'IndexName': 'DateSorted',
37 | 'KeyConditionExpression': "#userId = :userId",
38 | 'ExpressionAttributeNames': {
39 | '#userId': 'userId',
40 | },
41 | 'ExpressionAttributeValues': {
42 | ':userId': AWS.config.credentials.identityId
43 | },
44 | 'ScanIndexForward': false
45 | }).promise().then((data) => {
46 | this.items = data.Items;
47 | if (this.refresher) {
48 | this.refresher.complete();
49 | }
50 | }).catch((err) => {
51 | console.log(err);
52 | });
53 | }
54 |
55 | generateId() {
56 | var len = 16;
57 | var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
58 | var charLength = chars.length;
59 | var result = "";
60 | let randoms = window.crypto.getRandomValues(new Uint32Array(len));
61 | for(var i = 0; i < len; i++) {
62 | result += chars[randoms[i] % charLength];
63 | }
64 | return result.toLowerCase();
65 | }
66 |
67 | addTask() {
68 | let id = this.generateId();
69 | let addModal = this.modalCtrl.create(TasksCreatePage, { 'id': id });
70 | addModal.onDidDismiss(item => {
71 | if (item) {
72 | item.userId = AWS.config.credentials.identityId;
73 | item.created = (new Date().getTime() / 1000);
74 | this.db.getDocumentClient().put({
75 | 'TableName': this.taskTable,
76 | 'Item': item,
77 | 'ConditionExpression': 'attribute_not_exists(id)'
78 | }, (err, data) => {
79 | if (err) { console.log(err); }
80 | this.refreshTasks();
81 | });
82 | }
83 | })
84 | addModal.present();
85 | }
86 |
87 | deleteTask(task, index) {
88 | this.db.getDocumentClient().delete({
89 | 'TableName': this.taskTable,
90 | 'Key': {
91 | 'userId': AWS.config.credentials.identityId,
92 | 'taskId': task.taskId
93 | }
94 | }).promise().then((data) => {
95 | this.items.splice(index, 1);
96 | }).catch((err) => {
97 | console.log('there was an error', err);
98 | });
99 | }
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/src/pages/account/account.ts:
--------------------------------------------------------------------------------
1 | import { Component, ViewChild } from '@angular/core';
2 |
3 | import { Config, LoadingController, NavController } from 'ionic-angular';
4 |
5 | import { Camera, CameraOptions } from '@ionic-native/camera';
6 |
7 | import { DynamoDB, User } from '../../providers/providers';
8 |
9 | declare var AWS: any;
10 | declare const aws_user_files_s3_bucket;
11 | declare const aws_user_files_s3_bucket_region;
12 |
13 | @Component({
14 | selector: 'page-account',
15 | templateUrl: 'account.html'
16 | })
17 | export class AccountPage {
18 |
19 | @ViewChild('avatar') avatarInput;
20 |
21 | private s3: any;
22 | public avatarPhoto: string;
23 | public selectedPhoto: Blob;
24 | public attributes: any;
25 | public sub: string = null;
26 |
27 | constructor(public navCtrl: NavController,
28 | public user: User,
29 | public db: DynamoDB,
30 | public config: Config,
31 | public camera: Camera,
32 | public loadingCtrl: LoadingController) {
33 | this.attributes = [];
34 | this.avatarPhoto = null;
35 | this.selectedPhoto = null;
36 | this.s3 = new AWS.S3({
37 | 'params': {
38 | 'Bucket': aws_user_files_s3_bucket
39 | },
40 | 'region': aws_user_files_s3_bucket_region
41 | });
42 | this.sub = AWS.config.credentials.identityId;
43 | user.getUser().getUserAttributes((err, data) => {
44 | this.attributes = data;
45 | this.refreshAvatar();
46 | });
47 | }
48 |
49 | refreshAvatar() {
50 | this.s3.getSignedUrl('getObject', {'Key': 'protected/' + this.sub + '/avatar'}, (err, url) => {
51 | this.avatarPhoto = url;
52 | });
53 | }
54 |
55 | dataURItoBlob(dataURI) {
56 | // code adapted from: http://stackoverflow.com/questions/33486352/cant-upload-image-to-aws-s3-from-ionic-camera
57 | let binary = atob(dataURI.split(',')[1]);
58 | let array = [];
59 | for (let i = 0; i < binary.length; i++) {
60 | array.push(binary.charCodeAt(i));
61 | }
62 | return new Blob([new Uint8Array(array)], {type: 'image/jpeg'});
63 | };
64 |
65 | selectAvatar() {
66 | const options: CameraOptions = {
67 | quality: 100,
68 | targetHeight: 200,
69 | targetWidth: 200,
70 | destinationType: this.camera.DestinationType.DATA_URL,
71 | encodingType: this.camera.EncodingType.JPEG,
72 | mediaType: this.camera.MediaType.PICTURE
73 | }
74 |
75 | this.camera.getPicture(options).then((imageData) => {
76 | // imageData is either a base64 encoded string or a file URI
77 | // If it's base64:
78 | this.selectedPhoto = this.dataURItoBlob('data:image/jpeg;base64,' + imageData);
79 | this.upload();
80 | }, (err) => {
81 | this.avatarInput.nativeElement.click();
82 | // Handle error
83 | });
84 | }
85 |
86 | uploadFromFile(event) {
87 | const files = event.target.files;
88 | console.log('Uploading', files)
89 | var reader = new FileReader();
90 | reader.readAsDataURL(files[0]);
91 | reader.onload = () => {
92 | this.selectedPhoto = this.dataURItoBlob(reader.result);
93 | this.upload();
94 | };
95 | reader.onerror = (error) => {
96 | alert('Unable to load file. Please try another.')
97 | }
98 | }
99 |
100 | upload() {
101 | let loading = this.loadingCtrl.create({
102 | content: 'Uploading image...'
103 | });
104 | loading.present();
105 |
106 | if (this.selectedPhoto) {
107 | this.s3.upload({
108 | 'Key': 'protected/' + this.sub + '/avatar',
109 | 'Body': this.selectedPhoto,
110 | 'ContentType': 'image/jpeg'
111 | }).promise().then((data) => {
112 | this.refreshAvatar();
113 | console.log('upload complete:', data);
114 | loading.dismiss();
115 | }, err => {
116 | console.log('upload failed....', err);
117 | loading.dismiss();
118 | });
119 | } else {
120 | loading.dismiss();
121 | }
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/providers/user.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Config } from 'ionic-angular';
3 |
4 | import { Cognito } from './aws.cognito';
5 |
6 | declare var AWS: any;
7 | declare const aws_cognito_region;
8 | declare const aws_cognito_identity_pool_id;
9 | declare const aws_user_pools_id;
10 | declare const aws_user_pools_web_client_id;
11 |
12 | @Injectable()
13 | export class User {
14 |
15 | private user: any;
16 | public loggedIn: boolean = false;
17 |
18 | constructor(public cognito: Cognito, public config: Config) {
19 | this.user = null;
20 | }
21 |
22 | getUser() {
23 | return this.user;
24 | }
25 |
26 | getUsername() {
27 | return this.getUser().getUsername();
28 | }
29 |
30 | login(username, password) {
31 | return new Promise((resolve, reject) => {
32 | let user = this.cognito.makeUser(username);
33 | let authDetails = this.cognito.makeAuthDetails(username, password);
34 |
35 | user.authenticateUser(authDetails, {
36 | 'onSuccess': (result:any) => {
37 |
38 | var logins = {};
39 | var loginKey = 'cognito-idp.' +
40 | aws_cognito_region +
41 | '.amazonaws.com/' +
42 | aws_user_pools_id;
43 | logins[loginKey] = result.getIdToken().getJwtToken();
44 |
45 | AWS.config.credentials = new AWS.CognitoIdentityCredentials({
46 | 'IdentityPoolId': aws_cognito_identity_pool_id,
47 | 'Logins': logins
48 | });
49 |
50 | AWS.config.credentials.get((err) => {
51 | if (err) {
52 | return reject(err);
53 | }
54 |
55 | this.isAuthenticated().then(() => {
56 | resolve();
57 | }).catch((err) => {
58 | console.log('auth session failed');
59 | });
60 | });
61 |
62 | },
63 |
64 | 'onFailure': (err:any) => {
65 |
66 | console.log('authentication failed');
67 | reject(err);
68 |
69 | }
70 | });
71 | });
72 | }
73 |
74 | logout() {
75 | this.user = null;
76 | this.cognito.getUserPool().getCurrentUser().signOut();
77 | AWS.config.credentials.clearCachedId();
78 | }
79 |
80 | register(username, password, attr) {
81 | let attributes = [];
82 |
83 | for (var x in attr) {
84 | attributes.push(this.cognito.makeAttribute(x, attr[x]));
85 | }
86 |
87 | return new Promise((resolve, reject) => {
88 | this.cognito.getUserPool().signUp(username, password, attributes, null, function(err, result) {
89 | if (err) {
90 | reject(err);
91 | } else {
92 | resolve(result.user);
93 | }
94 | });
95 | });
96 | }
97 |
98 | confirmRegistration(username, code) {
99 | return new Promise((resolve, reject) => {
100 | let user = this.cognito.makeUser(username);
101 | user.confirmRegistration(code, true, (err, result) => {
102 | if (err) {
103 | console.log('could not confirm user', err);
104 | reject(err);
105 | } else {
106 | resolve(result);
107 | }
108 | });
109 | });
110 | }
111 |
112 | resendRegistrationCode(username) {
113 | return new Promise((resolve, reject) => {
114 | let user = this.cognito.makeUser(username);
115 | user.resendConfirmationCode((err, result) => {
116 | if (err) {
117 | console.log('could not resend code..', err);
118 | reject(err);
119 | } else {
120 | resolve();
121 | }
122 | });
123 | });
124 | }
125 |
126 | isAuthenticated() {
127 | return new Promise((resolve, reject) => {
128 | let user = this.cognito.getCurrentUser();
129 | if (user != null) {
130 | user.getSession((err, session) => {
131 | if (err) {
132 | console.log('rejected session');
133 | reject()
134 | } else {
135 | console.log('accepted session');
136 | var logins = {};
137 | var loginKey = 'cognito-idp.' +
138 | aws_cognito_region +
139 | '.amazonaws.com/' +
140 | aws_user_pools_id;
141 | logins[loginKey] = session.getIdToken().getJwtToken();
142 |
143 | AWS.config.credentials = new AWS.CognitoIdentityCredentials({
144 | 'IdentityPoolId': aws_cognito_identity_pool_id,
145 | 'Logins': logins
146 | });
147 |
148 | this.user = user;
149 | resolve()
150 | }
151 | });
152 | } else {
153 | reject()
154 | }
155 | });
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/src/assets/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 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("aws-sdk/global"),require("aws-sdk/clients/cognitoidentityserviceprovider")):"function"==typeof define&&define.amd?define(["aws-sdk/global","aws-sdk/clients/cognitoidentityserviceprovider"],t):"object"==typeof exports?exports.AmazonCognitoIdentity=t(require("aws-sdk/global"),require("aws-sdk/clients/cognitoidentityserviceprovider")):e.AmazonCognitoIdentity=t(e.AWSCognito,e.AWSCognito.CognitoIdentityServiceProvider)}(this,function(e,t){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(15);Object.keys(r).forEach(function(e){"default"!==e&&"__esModule"!==e&&Object.defineProperty(t,e,{enumerable:!0,get:function(){return r[e]}})});var o=n(12),a=s(o),u=i(r);Object.keys(u).forEach(function(e){a.default[e]=u[e]}),"undefined"!=typeof window&&!window.crypto&&window.msCrypto&&(window.crypto=window.msCrypto)},function(t,n){t.exports=e},function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}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;n=0;){var o=t*this[e++]+n[i]+s;s=Math.floor(o/67108864),n[i++]=67108863&o}return s}function r(e){return J.charAt(e)}function o(e,t){var n=G[e.charCodeAt(t)];return null==n?-1:n}function a(e){for(var t=this.t-1;t>=0;--t)e[t]=this[t];e.t=this.t,e.s=this.s}function u(e){this.t=1,this.s=e<0?-1:0,e>0?this[0]=e:e<-1?this[0]=e+this.DV:this.t=0}function l(e){var t=i();return t.fromInt(e),t}function c(e,t){var i;if(16==t)i=4;else if(8==t)i=3;else if(2==t)i=1;else if(32==t)i=5;else{if(4!=t)throw new Error("Only radix 2, 4, 8, 16, 32 are supported");i=2}this.t=0,this.s=0;for(var s=e.length,r=!1,a=0;--s>=0;){var u=o(e,s);u<0?"-"==e.charAt(s)&&(r=!0):(r=!1,0==a?this[this.t++]=u:a+i>this.DB?(this[this.t-1]|=(u&(1<>this.DB-a):this[this.t-1]|=u<=this.DB&&(a-=this.DB))}this.clamp(),r&&n.ZERO.subTo(this,this)}function h(){for(var e=this.s&this.DM;this.t>0&&this[this.t-1]==e;)--this.t}function f(e){if(this.s<0)return"-"+this.negate().toString();var t;if(16==e)t=4;else if(8==e)t=3;else if(2==e)t=1;else if(32==e)t=5;else{if(4!=e)throw new Error("Only radix 2, 4, 8, 16, 32 are supported");t=2}var n,i=(1<0)for(u>u)>0&&(s=!0,o=r(n));a>=0;)u>(u+=this.DB-t)):(n=this[a]>>(u-=t)&i,u<=0&&(u+=this.DB,--a)),n>0&&(s=!0),s&&(o+=r(n));return s?o:"0"}function d(){var e=i();return n.ZERO.subTo(this,e),e}function v(){return this.s<0?this.negate():this}function g(e){var t=this.s-e.s;if(0!=t)return t;var n=this.t;if(t=n-e.t,0!=t)return this.s<0?-t:t;for(;--n>=0;)if(0!=(t=this[n]-e[n]))return t;return 0}function m(e){var t,n=1;return 0!=(t=e>>>16)&&(e=t,n+=16),0!=(t=e>>8)&&(e=t,n+=8),0!=(t=e>>4)&&(e=t,n+=4),0!=(t=e>>2)&&(e=t,n+=2),0!=(t=e>>1)&&(e=t,n+=1),n}function p(){return this.t<=0?0:this.DB*(this.t-1)+m(this[this.t-1]^this.s&this.DM)}function y(e,t){var n;for(n=this.t-1;n>=0;--n)t[n+e]=this[n];for(n=e-1;n>=0;--n)t[n]=0;t.t=this.t+e,t.s=this.s}function S(e,t){for(var n=e;n=0;--n)t[n+o+1]=this[n]>>s|a,a=(this[n]&r)<=0;--n)t[n]=0;t[o]=a,t.t=this.t+o+1,t.s=this.s,t.clamp()}function w(e,t){t.s=this.s;var n=Math.floor(e/this.DB);if(n>=this.t)return void(t.t=0);var i=e%this.DB,s=this.DB-i,r=(1<>i;for(var o=n+1;o>i;i>0&&(t[this.t-n-1]|=(this.s&r)<>=this.DB;if(e.t>=this.DB;i+=this.s}else{for(i+=this.s;n>=this.DB;i-=e.s}t.s=i<0?-1:0,i<-1?t[n++]=this.DV+i:i>0&&(t[n++]=i),t.t=n,t.clamp()}function A(e,t){var i=this.abs(),s=e.abs(),r=i.t;for(t.t=r+s.t;--r>=0;)t[r]=0;for(r=0;r=0;)e[n]=0;for(n=0;n=t.DV&&(e[n+t.t]-=t.DV,e[n+t.t+1]=1)}e.t>0&&(e[e.t-1]+=t.am(n,t[n],e,2*n,0,1)),e.s=0,e.clamp()}function U(e,t,s){var r=e.abs();if(!(r.t<=0)){var o=this.abs();if(o.t0?(r.lShiftTo(c,a),o.lShiftTo(c,s)):(r.copyTo(a),o.copyTo(s));var h=a.t,f=a[h-1];if(0!=f){var d=f*(1<1?a[h-2]>>this.F2:0),v=this.FV/d,g=(1<=0&&(s[s.t++]=1,s.subTo(C,s)),n.ONE.dlShiftTo(h,C),C.subTo(a,a);a.t=0;){var w=s[--y]==f?this.DM:Math.floor(s[y]*v+(s[y-1]+p)*g);if((s[y]+=a.am(0,w,s,S,0,h))0&&s.rShiftTo(c,s),u<0&&n.ZERO.subTo(s,s)}}}function E(e){var t=i();return this.abs().divRemTo(e,null,t),this.s<0&&t.compareTo(n.ZERO)>0&&e.subTo(t,t),t}function D(){if(this.t<1)return 0;var e=this[0];if(0==(1&e))return 0;var t=3&e;return t=t*(2-(15&e)*t)&15,t=t*(2-(255&e)*t)&255,t=t*(2-((65535&e)*t&65535))&65535,t=t*(2-e*t%this.DV)%this.DV,t>0?this.DV-t:-t}function I(e){return 0==this.compareTo(e)}function b(e,t){for(var n=0,i=0,s=Math.min(e.t,this.t);n>=this.DB;if(e.t>=this.DB;i+=this.s}else{for(i+=this.s;n>=this.DB;i+=e.s}t.s=i<0?-1:0,i>0?t[n++]=i:i<-1&&(t[n++]=this.DV+i),t.t=n,t.clamp()}function P(e){var t=i();return this.addTo(e,t),t}function R(e){var t=i();return this.subTo(e,t),t}function F(e){var t=i();return this.multiplyTo(e,t),t}function _(e){var t=i();return this.divRemTo(e,t,null),t}function B(e){this.m=e,this.mp=e.invDigit(),this.mpl=32767&this.mp,this.mph=this.mp>>15,this.um=(1<0&&this.m.subTo(t,t),t}function M(e){var t=i();return e.copyTo(t),this.reduce(t),t}function N(e){for(;e.t<=this.mt2;)e[e.t++]=0;for(var t=0;t>15)*this.mpl&this.um)<<15)&e.DM;for(n=t+this.m.t,e[n]+=this.m.am(0,i,e,t,0,this.m.t);e[n]>=e.DV;)e[n]-=e.DV,e[++n]++}e.clamp(),e.drShiftTo(this.m.t,e),e.compareTo(this.m)>=0&&e.subTo(this.m,e)}function V(e,t){e.squareTo(t),this.reduce(t)}function K(e,t,n){e.multiplyTo(t,n),this.reduce(n)}function q(e,t){var n,s=e.bitLength(),r=l(1),o=new B(t);if(s<=0)return r;n=s<18?1:s<48?3:s<144?4:s<768?5:6;var a=new Array,u=3,c=n-1,h=(1<1){var f=i();for(o.sqrTo(a[1],f);u<=h;)a[u]=i(),o.mulTo(f,a[u-2],a[u]),u+=2}var d,v,g=e.t-1,p=!0,y=i();for(s=m(e[g])-1;g>=0;){for(s>=c?d=e[g]>>s-c&h:(d=(e[g]&(1<0&&(d|=e[g-1]>>this.DB+s-c)),u=n;0==(1&d);)d>>=1,--u;if((s-=u)<0&&(s+=this.DB,--g),p)a[d].copyTo(r),p=!1;else{for(;u>1;)o.sqrTo(r,y),o.sqrTo(y,r),u-=2;u>0?o.sqrTo(r,y):(v=r,r=y,y=v),o.mulTo(y,a[d],r)}for(;g>=0&&0==(e[g]&1<0&&void 0!==arguments[0]?arguments[0]:{},n=t.AccessToken;i(this,e),this.jwtToken=n||""}return s(e,[{key:"getJwtToken",value:function(){return this.jwtToken}},{key:"getExpiration",value:function(){var e=this.jwtToken.split(".")[1],t=JSON.parse(r.util.base64.decode(e).toString("utf8"));return t.exp}}]),e}();t.default=o},function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var s=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{},n=t.IdToken;i(this,e),this.jwtToken=n||""}return s(e,[{key:"getJwtToken",value:function(){return this.jwtToken}},{key:"getExpiration",value:function(){var e=this.jwtToken.split(".")[1],t=JSON.parse(r.util.base64.decode(e).toString("utf8"));return t.exp}}]),e}();t.default=o},function(e,t){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{},i=t.RefreshToken;n(this,e),this.token=i||""}return i(e,[{key:"getToken",value:function(){return this.token}}]),e}();t.default=s},function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}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;n0&&void 0!==arguments[0]?arguments[0]:{},i=t.Name,s=t.Value;n(this,e),this.Name=i||"",this.Value=s||""}return i(e,[{key:"getValue",value:function(){return this.Value}},{key:"setValue",value:function(e){return this.Value=e,this}},{key:"getName",value:function(){return this.Name}},{key:"setName",value:function(e){return this.Name=e,this}},{key:"toString",value:function(){return JSON.stringify(this)}},{key:"toJSON",value:function(){return{Name:this.Name,Value:this.Value}}}]),e}();t.default=s},function(e,t){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{},i=t.IdToken,s=t.RefreshToken,r=t.AccessToken;if(n(this,e),null==r||null==i)throw new Error("Id token and Access Token must be present.");this.idToken=i,this.refreshToken=s,this.accessToken=r}return i(e,[{key:"getIdToken",value:function(){return this.idToken}},{key:"getRefreshToken",value:function(){return this.refreshToken}},{key:"getAccessToken",value:function(){return this.accessToken}},{key:"isValid",value:function(){var e=Math.floor(new Date/1e3);return e