@sneat/auth-ui 0.1.3 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/index.js +4 -0
- package/esm2022/index.js.map +1 -0
- package/esm2022/lib/components/auth-menu-item/auth-menu-item.component.js +82 -0
- package/esm2022/lib/components/auth-menu-item/auth-menu-item.component.js.map +1 -0
- package/esm2022/lib/components/index.js +4 -0
- package/esm2022/lib/components/index.js.map +1 -0
- package/esm2022/lib/components/user-auth-providers/user-auth-accounts.component.js +83 -0
- package/esm2022/lib/components/user-auth-providers/user-auth-accounts.component.js.map +1 -0
- package/esm2022/lib/components/user-auth-providers/user-auth-provider-status.js +118 -0
- package/esm2022/lib/components/user-auth-providers/user-auth-provider-status.js.map +1 -0
- package/esm2022/lib/components/user-required-fields/index.js +3 -0
- package/esm2022/lib/components/user-required-fields/index.js.map +1 -0
- package/esm2022/lib/components/user-required-fields/user-required-fields-modal.component.js +111 -0
- package/esm2022/lib/components/user-required-fields/user-required-fields-modal.component.js.map +1 -0
- package/esm2022/lib/components/user-required-fields/user-required-fields.service.js +29 -0
- package/esm2022/lib/components/user-required-fields/user-required-fields.service.js.map +1 -0
- package/esm2022/lib/pages/login-page/email-login-form/email-login-form.component.js +263 -0
- package/esm2022/lib/pages/login-page/email-login-form/email-login-form.component.js.map +1 -0
- package/esm2022/lib/pages/login-page/login-page.component.js +143 -0
- package/esm2022/lib/pages/login-page/login-page.component.js.map +1 -0
- package/esm2022/lib/pages/login-page/login-with-telegram.component.js +93 -0
- package/esm2022/lib/pages/login-page/login-with-telegram.component.js.map +1 -0
- package/esm2022/lib/pages/login-page/sneat-auth-with-telegram.service.js +31 -0
- package/esm2022/lib/pages/login-page/sneat-auth-with-telegram.service.js.map +1 -0
- package/esm2022/lib/pages/sign-in-from-email-link/sign-in-from-email-link-page.component.js +52 -0
- package/esm2022/lib/pages/sign-in-from-email-link/sign-in-from-email-link-page.component.js.map +1 -0
- package/esm2022/lib/pages/sneat-auth-routing.module.js +27 -0
- package/esm2022/lib/pages/sneat-auth-routing.module.js.map +1 -0
- package/esm2022/lib/pipes/person-names.pipe.js +35 -0
- package/esm2022/lib/pipes/person-names.pipe.js.map +1 -0
- package/esm2022/sneat-auth-ui.js +5 -0
- package/esm2022/sneat-auth-ui.js.map +1 -0
- package/lib/components/auth-menu-item/auth-menu-item.component.d.ts +24 -0
- package/lib/components/user-auth-providers/user-auth-accounts.component.d.ts +17 -0
- package/lib/components/user-auth-providers/user-auth-provider-status.d.ts +31 -0
- package/lib/components/user-required-fields/user-required-fields-modal.component.d.ts +31 -0
- package/lib/components/user-required-fields/user-required-fields.service.d.ts +7 -0
- package/lib/pages/login-page/email-login-form/email-login-form.component.d.ts +51 -0
- package/lib/pages/login-page/login-page.component.d.ts +30 -0
- package/lib/pages/login-page/login-with-telegram.component.d.ts +17 -0
- package/lib/pages/login-page/sneat-auth-with-telegram.service.d.ts +18 -0
- package/lib/pages/sign-in-from-email-link/sign-in-from-email-link-page.component.d.ts +13 -0
- package/lib/pages/sneat-auth-routing.module.d.ts +9 -0
- package/lib/pipes/person-names.pipe.d.ts +9 -0
- package/package.json +14 -2
- package/sneat-auth-ui.d.ts +5 -0
- package/tsconfig.lib.prod.tsbuildinfo +1 -0
- package/eslint.config.cjs +0 -7
- package/ng-package.json +0 -7
- package/project.json +0 -38
- package/src/lib/components/auth-menu-item/auth-menu-item.component.html +0 -59
- package/src/lib/components/auth-menu-item/auth-menu-item.component.spec.ts +0 -5
- package/src/lib/components/auth-menu-item/auth-menu-item.component.ts +0 -116
- package/src/lib/components/user-auth-providers/user-auth-accounts.component.html +0 -127
- package/src/lib/components/user-auth-providers/user-auth-accounts.component.spec.ts +0 -47
- package/src/lib/components/user-auth-providers/user-auth-accounts.component.ts +0 -109
- package/src/lib/components/user-auth-providers/user-auth-provider-status.html +0 -42
- package/src/lib/components/user-auth-providers/user-auth-provider-status.ts +0 -172
- package/src/lib/components/user-required-fields/user-required-fields-modal.component.html +0 -64
- package/src/lib/components/user-required-fields/user-required-fields-modal.component.spec.ts +0 -45
- package/src/lib/components/user-required-fields/user-required-fields-modal.component.ts +0 -141
- package/src/lib/components/user-required-fields/user-required-fields.service.spec.ts +0 -335
- package/src/lib/components/user-required-fields/user-required-fields.service.ts +0 -23
- package/src/lib/pages/login-page/email-login-form/email-login-form.component.html +0 -165
- package/src/lib/pages/login-page/email-login-form/email-login-form.component.spec.ts +0 -59
- package/src/lib/pages/login-page/email-login-form/email-login-form.component.ts +0 -356
- package/src/lib/pages/login-page/index.ts +0 -3
- package/src/lib/pages/login-page/login-page.component.html +0 -146
- package/src/lib/pages/login-page/login-page.component.spec.ts +0 -5
- package/src/lib/pages/login-page/login-page.component.ts +0 -209
- package/src/lib/pages/login-page/login-with-telegram.component.spec.ts +0 -42
- package/src/lib/pages/login-page/login-with-telegram.component.ts +0 -82
- package/src/lib/pages/login-page/sneat-auth-with-telegram.service.spec.ts +0 -31
- package/src/lib/pages/login-page/sneat-auth-with-telegram.service.ts +0 -56
- package/src/lib/pages/sign-in-from-email-link/sign-in-from-email-link-page.component.html +0 -35
- package/src/lib/pages/sign-in-from-email-link/sign-in-from-email-link-page.component.spec.ts +0 -43
- package/src/lib/pages/sign-in-from-email-link/sign-in-from-email-link-page.component.ts +0 -70
- package/src/lib/pages/sneat-auth-routing.module.ts +0 -25
- package/src/lib/pipes/person-names.pipe.spec.ts +0 -317
- package/src/lib/pipes/person-names.pipe.ts +0 -31
- package/src/test-setup.ts +0 -3
- package/tsconfig.json +0 -13
- package/tsconfig.lib.json +0 -19
- package/tsconfig.lib.prod.json +0 -7
- package/tsconfig.spec.json +0 -31
- package/vite.config.mts +0 -10
- /package/{src/index.ts → index.d.ts} +0 -0
- /package/{src/lib/components/index.ts → lib/components/index.d.ts} +0 -0
- /package/{src/lib/components/user-required-fields/index.ts → lib/components/user-required-fields/index.d.ts} +0 -0
package/eslint.config.cjs
DELETED
package/ng-package.json
DELETED
package/project.json
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "auth-ui",
|
|
3
|
-
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
-
"projectType": "library",
|
|
5
|
-
"sourceRoot": "libs/auth/ui/src",
|
|
6
|
-
"prefix": "sneat",
|
|
7
|
-
"targets": {
|
|
8
|
-
"build": {
|
|
9
|
-
"executor": "@nx/angular:ng-packagr-lite",
|
|
10
|
-
"outputs": [
|
|
11
|
-
"{workspaceRoot}/dist/libs/auth/ui"
|
|
12
|
-
],
|
|
13
|
-
"options": {
|
|
14
|
-
"project": "libs/auth/ui/ng-package.json",
|
|
15
|
-
"tsConfig": "libs/auth/ui/tsconfig.lib.json"
|
|
16
|
-
},
|
|
17
|
-
"configurations": {
|
|
18
|
-
"production": {
|
|
19
|
-
"tsConfig": "libs/auth/ui/tsconfig.lib.prod.json"
|
|
20
|
-
},
|
|
21
|
-
"development": {}
|
|
22
|
-
},
|
|
23
|
-
"defaultConfiguration": "production"
|
|
24
|
-
},
|
|
25
|
-
"test": {
|
|
26
|
-
"executor": "@nx/vitest:test",
|
|
27
|
-
"outputs": [
|
|
28
|
-
"{workspaceRoot}/coverage/libs/auth/ui"
|
|
29
|
-
],
|
|
30
|
-
"options": {
|
|
31
|
-
"tsConfig": "libs/auth/ui/tsconfig.spec.json"
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
"lint": {
|
|
35
|
-
"executor": "@nx/eslint:lint"
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
<ion-item-divider color="light">
|
|
2
|
-
@if ($authStatus() === "authenticated") {
|
|
3
|
-
<ion-label>Signed in as</ion-label>
|
|
4
|
-
} @else {
|
|
5
|
-
<ion-label>Authentication</ion-label>
|
|
6
|
-
}
|
|
7
|
-
</ion-item-divider>
|
|
8
|
-
@if (!$authState()) {
|
|
9
|
-
<ion-item>
|
|
10
|
-
<ion-label>Loading....</ion-label>
|
|
11
|
-
</ion-item>
|
|
12
|
-
} @else if ($isAuthenticating()) {
|
|
13
|
-
<ion-item routerLink="login">
|
|
14
|
-
<ion-label>Authenticating....</ion-label>
|
|
15
|
-
</ion-item>
|
|
16
|
-
}
|
|
17
|
-
@if ($authStatus() === "notAuthenticated") {
|
|
18
|
-
<ion-item routerLink="/login" tappable="true">
|
|
19
|
-
<ion-icon slot="start" name="person-circle-outline" />
|
|
20
|
-
<ion-label color="primary"> Please sign in</ion-label>
|
|
21
|
-
</ion-item>
|
|
22
|
-
}
|
|
23
|
-
@if ($authStatus() === "authenticated") {
|
|
24
|
-
<ion-item
|
|
25
|
-
tappable="true"
|
|
26
|
-
routerLink="/my"
|
|
27
|
-
routerDirection="forward"
|
|
28
|
-
(click)="closeMenu()"
|
|
29
|
-
>
|
|
30
|
-
<!-- <ion-buttons slot="start" class="ion-no-margin">-->
|
|
31
|
-
<!-- <ion-button disabled color="medium" >-->
|
|
32
|
-
<!-- <ion-icon slot="start" name="person-circle-outline"></ion-icon>-->
|
|
33
|
-
<!-- </ion-button>-->
|
|
34
|
-
<!-- </ion-buttons>-->
|
|
35
|
-
<ion-icon slot="start" name="person-circle-outline" />
|
|
36
|
-
|
|
37
|
-
<ion-label color="medium">
|
|
38
|
-
@if ($user()?.record?.names; as names) {
|
|
39
|
-
{{ names | personNames }}
|
|
40
|
-
} @else {
|
|
41
|
-
@if ($authState()?.user; as user) {
|
|
42
|
-
{{ user.displayName || user.email || user.phoneNumber || user.uid }}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
</ion-label>
|
|
46
|
-
|
|
47
|
-
<ion-buttons slot="end">
|
|
48
|
-
<!-- <ion-button color="medium" title="Settings">-->
|
|
49
|
-
<!-- <ion-icon name="settings-outline"></ion-icon>-->
|
|
50
|
-
<!-- </ion-button>-->
|
|
51
|
-
<ion-button color="medium" title="Sign-out" (click)="logout($event)">
|
|
52
|
-
<ion-icon name="log-out-outline" />
|
|
53
|
-
</ion-button>
|
|
54
|
-
</ion-buttons>
|
|
55
|
-
</ion-item>
|
|
56
|
-
}
|
|
57
|
-
@if ($err()) {
|
|
58
|
-
<ion-item> ERROR: {{ $err() | json }}</ion-item>
|
|
59
|
-
}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import { JsonPipe } from '@angular/common';
|
|
2
|
-
import {
|
|
3
|
-
ChangeDetectionStrategy,
|
|
4
|
-
Component,
|
|
5
|
-
computed,
|
|
6
|
-
signal,
|
|
7
|
-
OnDestroy,
|
|
8
|
-
inject,
|
|
9
|
-
} from '@angular/core';
|
|
10
|
-
import { RouterModule } from '@angular/router';
|
|
11
|
-
import {
|
|
12
|
-
IonButton,
|
|
13
|
-
IonButtons,
|
|
14
|
-
IonIcon,
|
|
15
|
-
IonItem,
|
|
16
|
-
IonItemDivider,
|
|
17
|
-
IonLabel,
|
|
18
|
-
MenuController,
|
|
19
|
-
NavController,
|
|
20
|
-
} from '@ionic/angular/standalone';
|
|
21
|
-
import {
|
|
22
|
-
ISneatAuthState,
|
|
23
|
-
ISneatUserState,
|
|
24
|
-
SneatAuthStateService,
|
|
25
|
-
SneatUserService,
|
|
26
|
-
} from '@sneat/auth-core';
|
|
27
|
-
import { ErrorLogger, IErrorLogger } from '@sneat/core';
|
|
28
|
-
import { Subject, takeUntil } from 'rxjs';
|
|
29
|
-
import { PersonNamesPipe, personNames } from '../../pipes/person-names.pipe';
|
|
30
|
-
@Component({
|
|
31
|
-
selector: 'sneat-auth-menu-item',
|
|
32
|
-
templateUrl: './auth-menu-item.component.html',
|
|
33
|
-
imports: [
|
|
34
|
-
RouterModule,
|
|
35
|
-
PersonNamesPipe,
|
|
36
|
-
IonItemDivider,
|
|
37
|
-
IonLabel,
|
|
38
|
-
IonItem,
|
|
39
|
-
IonIcon,
|
|
40
|
-
IonButtons,
|
|
41
|
-
IonButton,
|
|
42
|
-
JsonPipe,
|
|
43
|
-
],
|
|
44
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
45
|
-
})
|
|
46
|
-
export class AuthMenuItemComponent implements OnDestroy {
|
|
47
|
-
private readonly errorLogger = inject<IErrorLogger>(ErrorLogger);
|
|
48
|
-
private readonly navCtrl = inject(NavController);
|
|
49
|
-
private readonly authStateService = inject(SneatAuthStateService);
|
|
50
|
-
private readonly menuController = inject(MenuController);
|
|
51
|
-
|
|
52
|
-
protected readonly $user = signal<ISneatUserState | undefined>(undefined);
|
|
53
|
-
protected $err = signal<unknown>(undefined);
|
|
54
|
-
|
|
55
|
-
protected readonly $authState = signal<ISneatAuthState | undefined>(
|
|
56
|
-
undefined,
|
|
57
|
-
);
|
|
58
|
-
protected readonly $authStatus = computed(() => this.$authState()?.status);
|
|
59
|
-
protected readonly $isAuthenticating = computed(
|
|
60
|
-
() => this.$authStatus() === 'authenticating',
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
protected readonly $destroyed = new Subject<void>();
|
|
64
|
-
|
|
65
|
-
public ngOnDestroy(): void {
|
|
66
|
-
this.$destroyed.next();
|
|
67
|
-
this.$destroyed.complete();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
constructor() {
|
|
71
|
-
const errorLogger = this.errorLogger;
|
|
72
|
-
const authStateService = this.authStateService;
|
|
73
|
-
const userService = inject(SneatUserService);
|
|
74
|
-
|
|
75
|
-
userService.userState
|
|
76
|
-
.pipe(takeUntil(this.$destroyed))
|
|
77
|
-
.subscribe(this.$user.set);
|
|
78
|
-
authStateService.authState.pipe(takeUntil(this.$destroyed)).subscribe({
|
|
79
|
-
next: this.$authState.set,
|
|
80
|
-
error: (err) => {
|
|
81
|
-
this.$err.set(err);
|
|
82
|
-
errorLogger.logError('failed to get auth state');
|
|
83
|
-
},
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
public closeMenu(): void {
|
|
88
|
-
this.menuController
|
|
89
|
-
.close()
|
|
90
|
-
.catch(this.errorLogger.logErrorHandler('Failed to close menu'));
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
public logout(event: Event): boolean {
|
|
94
|
-
event.stopPropagation();
|
|
95
|
-
event.preventDefault();
|
|
96
|
-
try {
|
|
97
|
-
this.authStateService
|
|
98
|
-
.signOut()
|
|
99
|
-
.then(() => {
|
|
100
|
-
this.navCtrl
|
|
101
|
-
.navigateBack('/signed-out')
|
|
102
|
-
.catch(
|
|
103
|
-
this.errorLogger.logErrorHandler(
|
|
104
|
-
'Failed to navigate to signed out page',
|
|
105
|
-
),
|
|
106
|
-
);
|
|
107
|
-
})
|
|
108
|
-
.catch(this.errorLogger.logErrorHandler('Failed to sign out'));
|
|
109
|
-
} catch (e) {
|
|
110
|
-
this.errorLogger.logError(e, 'Failed to logout');
|
|
111
|
-
}
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
protected readonly personName = personNames;
|
|
116
|
-
}
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
<ion-card>
|
|
2
|
-
<!-- <ion-item color="light" lines="full">-->
|
|
3
|
-
<!-- <ion-label color="medium"-->
|
|
4
|
-
<!-- ><h2 style="font-weight: bold">Authentication</h2></ion-label-->
|
|
5
|
-
<!-- >-->
|
|
6
|
-
<!-- </ion-item>-->
|
|
7
|
-
<!-- <ion-accordion-group [value]="integrations">-->
|
|
8
|
-
<!-- <ion-accordion value="messaging-apps">-->
|
|
9
|
-
<!-- <ion-item slot="header" color="light">-->
|
|
10
|
-
<!-- <ion-label>First Accordion</ion-label>-->
|
|
11
|
-
<!-- </ion-item>-->
|
|
12
|
-
<!-- <div class="ion-padding" slot="content">First Content</div>-->
|
|
13
|
-
<!-- </ion-accordion>-->
|
|
14
|
-
<!-- <ion-accordion value="quick-logins">-->
|
|
15
|
-
<!-- <ion-item slot="header" color="light">-->
|
|
16
|
-
<!-- <ion-label>Second Accordion</ion-label>-->
|
|
17
|
-
<!-- </ion-item>-->
|
|
18
|
-
<!-- <div class="ion-padding" slot="content">Second Content</div>-->
|
|
19
|
-
<!-- </ion-accordion>-->
|
|
20
|
-
<!-- </ion-accordion-group>-->
|
|
21
|
-
<!-- <ion-item>-->
|
|
22
|
-
<!-- <ion-segment [(ngModel)]="integrations" style="margin-bottom: 0.5em">-->
|
|
23
|
-
<!-- <ion-segment-button value="messaging-apps"-->
|
|
24
|
-
<!-- >Messaging Apps-->
|
|
25
|
-
<!-- </ion-segment-button>-->
|
|
26
|
-
<!-- <ion-segment-button value="quick-logins">Quick logins</ion-segment-button>-->
|
|
27
|
-
<!-- </ion-segment>-->
|
|
28
|
-
<!-- </ion-item>-->
|
|
29
|
-
<ion-list>
|
|
30
|
-
<ion-item-divider color="light">
|
|
31
|
-
<ion-label color="medium" style="font-weight: bold"
|
|
32
|
-
>Quick logins</ion-label
|
|
33
|
-
>
|
|
34
|
-
</ion-item-divider>
|
|
35
|
-
<sneat-user-auth-provider-status
|
|
36
|
-
providerID="google.com"
|
|
37
|
-
[signingInWith]="signingInWith()"
|
|
38
|
-
(signingInWithChange)="signingInWith.set($event)"
|
|
39
|
-
/>
|
|
40
|
-
<sneat-user-auth-provider-status
|
|
41
|
-
providerID="apple.com"
|
|
42
|
-
[signingInWith]="signingInWith()"
|
|
43
|
-
(signingInWithChange)="signingInWith.set($event)"
|
|
44
|
-
/>
|
|
45
|
-
<sneat-user-auth-provider-status
|
|
46
|
-
providerID="microsoft.com"
|
|
47
|
-
[signingInWith]="signingInWith()"
|
|
48
|
-
(signingInWithChange)="signingInWith.set($event)"
|
|
49
|
-
/>
|
|
50
|
-
</ion-list>
|
|
51
|
-
<ion-list>
|
|
52
|
-
<ion-item-divider color="light">
|
|
53
|
-
<ion-label color="medium" style="font-weight: bold"
|
|
54
|
-
>Messaging apps</ion-label
|
|
55
|
-
>
|
|
56
|
-
</ion-item-divider>
|
|
57
|
-
|
|
58
|
-
<ion-item>
|
|
59
|
-
<ion-icon slot="start" name="paper-plane" color="primary"></ion-icon>
|
|
60
|
-
@if (!$userRecord()) {
|
|
61
|
-
<ion-label>
|
|
62
|
-
<h3>Telegram</h3>
|
|
63
|
-
<p>Checking....</p>
|
|
64
|
-
</ion-label>
|
|
65
|
-
} @else if (hasAccount("telegram")) {
|
|
66
|
-
<ion-label>
|
|
67
|
-
<h3 style="font-weight: bold">Telegram</h3>
|
|
68
|
-
<ion-text color="success" [title]="getAccountID('telegram')"
|
|
69
|
-
>Connected!
|
|
70
|
-
</ion-text>
|
|
71
|
-
</ion-label>
|
|
72
|
-
<ion-buttons slot="end">
|
|
73
|
-
<ion-button
|
|
74
|
-
[disabled]="disconnecting"
|
|
75
|
-
color="warning"
|
|
76
|
-
fill="solid"
|
|
77
|
-
(click)="disconnect('telegram')"
|
|
78
|
-
>
|
|
79
|
-
<ion-icon name="close-outline" slot="start"></ion-icon>
|
|
80
|
-
<ion-label>Disconnect</ion-label>
|
|
81
|
-
</ion-button>
|
|
82
|
-
</ion-buttons>
|
|
83
|
-
} @else {
|
|
84
|
-
<ion-label>
|
|
85
|
-
<h3>Telegram</h3>
|
|
86
|
-
<p>Not connected yet.</p>
|
|
87
|
-
</ion-label>
|
|
88
|
-
<ion-buttons slot="end">
|
|
89
|
-
<sneat-login-with-telegram [isUserAuthenticated]="true" />
|
|
90
|
-
</ion-buttons>
|
|
91
|
-
}
|
|
92
|
-
</ion-item>
|
|
93
|
-
<ion-item>
|
|
94
|
-
<ion-icon slot="start" name="logo-whatsapp"></ion-icon>
|
|
95
|
-
<ion-label color="medium">
|
|
96
|
-
<h3 style="font-weight: bold">WhatsApp</h3>
|
|
97
|
-
<p>Not implemented yet - coming soon!</p>
|
|
98
|
-
</ion-label>
|
|
99
|
-
<!-- <ion-buttons slot="end">-->
|
|
100
|
-
<!-- <ion-button color="danger">-->
|
|
101
|
-
<!-- <ion-icon name="close-circle-outline" slot="start"></ion-icon>-->
|
|
102
|
-
<!-- <ion-label>I have no WhatsApp</ion-label>-->
|
|
103
|
-
<!-- </ion-button>-->
|
|
104
|
-
<!-- </ion-buttons>-->
|
|
105
|
-
</ion-item>
|
|
106
|
-
<ion-item>
|
|
107
|
-
<ion-icon slot="start" name="logo-whatsapp"></ion-icon>
|
|
108
|
-
<!-- TODO: place Viber logo here -->
|
|
109
|
-
<ion-label color="medium">
|
|
110
|
-
<h3 style="font-weight: bold">Viber</h3>
|
|
111
|
-
<p>Not implemented yet - coming soon!</p>
|
|
112
|
-
</ion-label>
|
|
113
|
-
</ion-item>
|
|
114
|
-
</ion-list>
|
|
115
|
-
<ion-card-content>
|
|
116
|
-
<p>
|
|
117
|
-
You'll get much more out of Sneat.app if you integrate it with messaging
|
|
118
|
-
apps you use. Benefits:
|
|
119
|
-
</p>
|
|
120
|
-
<ul>
|
|
121
|
-
<li>Easily add contacts</li>
|
|
122
|
-
<li>Get reminders</li>
|
|
123
|
-
<li>Add todo/to_buy from your messenger</li>
|
|
124
|
-
<li>etc.</li>
|
|
125
|
-
</ul>
|
|
126
|
-
</ion-card-content>
|
|
127
|
-
</ion-card>
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
2
|
-
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
|
3
|
-
import { SneatApiService } from '@sneat/api';
|
|
4
|
-
import { SneatUserService } from '@sneat/auth-core';
|
|
5
|
-
import { ErrorLogger } from '@sneat/core';
|
|
6
|
-
import { ClassName } from '@sneat/ui';
|
|
7
|
-
import { of } from 'rxjs';
|
|
8
|
-
import { UserAuthAccountsComponent } from './user-auth-accounts.component';
|
|
9
|
-
|
|
10
|
-
describe('UserAuthAccountsComponent', () => {
|
|
11
|
-
let component: UserAuthAccountsComponent;
|
|
12
|
-
let fixture: ComponentFixture<UserAuthAccountsComponent>;
|
|
13
|
-
|
|
14
|
-
beforeEach(waitForAsync(async () => {
|
|
15
|
-
await TestBed.configureTestingModule({
|
|
16
|
-
imports: [UserAuthAccountsComponent],
|
|
17
|
-
providers: [
|
|
18
|
-
{ provide: ClassName, useValue: 'TestComponent' },
|
|
19
|
-
{
|
|
20
|
-
provide: ErrorLogger,
|
|
21
|
-
useValue: { logError: vi.fn(), logErrorHandler: () => vi.fn() },
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
provide: SneatUserService,
|
|
25
|
-
useValue: {
|
|
26
|
-
userState: of({ record: undefined }),
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
provide: SneatApiService,
|
|
31
|
-
useValue: { delete: vi.fn() },
|
|
32
|
-
},
|
|
33
|
-
],
|
|
34
|
-
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
35
|
-
})
|
|
36
|
-
.overrideComponent(UserAuthAccountsComponent, {
|
|
37
|
-
set: { imports: [], schemas: [CUSTOM_ELEMENTS_SCHEMA] },
|
|
38
|
-
})
|
|
39
|
-
.compileComponents();
|
|
40
|
-
fixture = TestBed.createComponent(UserAuthAccountsComponent);
|
|
41
|
-
component = fixture.componentInstance;
|
|
42
|
-
}));
|
|
43
|
-
|
|
44
|
-
it('should create', () => {
|
|
45
|
-
expect(component).toBeTruthy();
|
|
46
|
-
});
|
|
47
|
-
});
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ChangeDetectionStrategy,
|
|
3
|
-
Component,
|
|
4
|
-
signal,
|
|
5
|
-
inject,
|
|
6
|
-
} from '@angular/core';
|
|
7
|
-
import { FormsModule } from '@angular/forms';
|
|
8
|
-
import {
|
|
9
|
-
IonButton,
|
|
10
|
-
IonButtons,
|
|
11
|
-
IonCard,
|
|
12
|
-
IonCardContent,
|
|
13
|
-
IonIcon,
|
|
14
|
-
IonItem,
|
|
15
|
-
IonItemDivider,
|
|
16
|
-
IonLabel,
|
|
17
|
-
IonList,
|
|
18
|
-
IonText,
|
|
19
|
-
} from '@ionic/angular/standalone';
|
|
20
|
-
import { SneatApiService } from '@sneat/api';
|
|
21
|
-
import { AuthProviderID, SneatUserService } from '@sneat/auth-core';
|
|
22
|
-
import { IUserRecord } from '@sneat/auth-models';
|
|
23
|
-
import { ClassName, SneatBaseComponent } from '@sneat/ui';
|
|
24
|
-
import { LoginWithTelegramComponent } from '../../pages/login-page/login-with-telegram.component';
|
|
25
|
-
import { UserAuthAProviderStatusComponent } from './user-auth-provider-status';
|
|
26
|
-
|
|
27
|
-
@Component({
|
|
28
|
-
selector: 'sneat-user-auth-accounts',
|
|
29
|
-
templateUrl: './user-auth-accounts.component.html',
|
|
30
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
31
|
-
imports: [
|
|
32
|
-
LoginWithTelegramComponent,
|
|
33
|
-
FormsModule,
|
|
34
|
-
UserAuthAProviderStatusComponent,
|
|
35
|
-
IonCard,
|
|
36
|
-
IonList,
|
|
37
|
-
IonItemDivider,
|
|
38
|
-
IonLabel,
|
|
39
|
-
IonItem,
|
|
40
|
-
IonIcon,
|
|
41
|
-
IonText,
|
|
42
|
-
IonButtons,
|
|
43
|
-
IonButton,
|
|
44
|
-
IonCardContent,
|
|
45
|
-
],
|
|
46
|
-
providers: [
|
|
47
|
-
{
|
|
48
|
-
provide: ClassName,
|
|
49
|
-
useValue: 'UserAuthAccountsComponent',
|
|
50
|
-
},
|
|
51
|
-
],
|
|
52
|
-
})
|
|
53
|
-
export class UserAuthAccountsComponent extends SneatBaseComponent {
|
|
54
|
-
private readonly sneatUserService = inject(SneatUserService);
|
|
55
|
-
private readonly sneatApiService = inject(SneatApiService);
|
|
56
|
-
|
|
57
|
-
protected readonly $userRecord = signal<IUserRecord | undefined>(undefined);
|
|
58
|
-
|
|
59
|
-
protected readonly signingInWith = signal<AuthProviderID | undefined>(
|
|
60
|
-
undefined,
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
constructor() {
|
|
64
|
-
super();
|
|
65
|
-
this.sneatUserService.userState.pipe(this.takeUntilDestroyed()).subscribe({
|
|
66
|
-
next: (user) => {
|
|
67
|
-
this.$userRecord.set(user.record || undefined);
|
|
68
|
-
},
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
protected hasAccount(provider: 'telegram' | 'viber' | 'whatsapp'): boolean {
|
|
73
|
-
provider = provider + ':';
|
|
74
|
-
for (const account of this.$userRecord()?.accounts || []) {
|
|
75
|
-
if (account.startsWith(provider)) {
|
|
76
|
-
return true;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return false;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
protected getAccountID(provider: 'telegram'): string {
|
|
83
|
-
const prefix = provider + '::';
|
|
84
|
-
const a = this.$userRecord()?.accounts?.find((a) => a.startsWith(prefix));
|
|
85
|
-
return a?.replace(prefix, '') || '';
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
protected disconnecting?: 'telegram' | 'viber' | 'whatsapp';
|
|
89
|
-
|
|
90
|
-
protected disconnect(provider: 'telegram'): void {
|
|
91
|
-
if (
|
|
92
|
-
!confirm(
|
|
93
|
-
'Are you sure you want to disconnect Telegram login from your account?',
|
|
94
|
-
)
|
|
95
|
-
) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
this.disconnecting = provider;
|
|
99
|
-
this.sneatApiService
|
|
100
|
-
.delete('auth/disconnect?provider=' + provider)
|
|
101
|
-
.subscribe({
|
|
102
|
-
next: () => {
|
|
103
|
-
this.disconnecting = undefined;
|
|
104
|
-
alert('Disconnected!');
|
|
105
|
-
},
|
|
106
|
-
error: this.errorLogger.logErrorHandler('Failed to disconnect'),
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
<ion-item>
|
|
2
|
-
<ion-icon [color]="provider().color" [name]="provider().icon" slot="start" />
|
|
3
|
-
<ion-label>
|
|
4
|
-
<h3>{{ provider().title || providerID() }}</h3>
|
|
5
|
-
<p>
|
|
6
|
-
@if(isConnected()) { Connected as
|
|
7
|
-
<b>{{authProviderUserInfo()?.displayName}}</b>
|
|
8
|
-
‐
|
|
9
|
-
<a href="mailto:{{authProviderUserInfo()?.email}}"
|
|
10
|
-
>{{authProviderUserInfo()?.email}}</a
|
|
11
|
-
>. } @else { Not connected yet. }
|
|
12
|
-
</p>
|
|
13
|
-
</ion-label>
|
|
14
|
-
<ion-buttons slot="end">
|
|
15
|
-
@if (isConnected()) {
|
|
16
|
-
<ion-button color="medium" fill="outline" (click)="disconnect()">
|
|
17
|
-
<ion-icon name="close-circle-outline" slot="start"></ion-icon>
|
|
18
|
-
<ion-label>
|
|
19
|
-
@if (isSigningIn()) { Disconnecting... } @else { Disconnect }
|
|
20
|
-
</ion-label>
|
|
21
|
-
</ion-button>
|
|
22
|
-
} @else {
|
|
23
|
-
<ion-button
|
|
24
|
-
[disabled]="isDisabled()"
|
|
25
|
-
[color]="provider().color"
|
|
26
|
-
[fill]="'solid'"
|
|
27
|
-
(click)="connect()"
|
|
28
|
-
>
|
|
29
|
-
@if (isSigningIn()) {
|
|
30
|
-
<ion-spinner slot="start" name="lines-small" />
|
|
31
|
-
} @else {
|
|
32
|
-
<ion-icon slot="start" [name]="provider().icon" />
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
<ion-label>
|
|
36
|
-
@if (signingInWith() === providerID()) { Signing in... } @else { Connect
|
|
37
|
-
}
|
|
38
|
-
</ion-label>
|
|
39
|
-
</ion-button>
|
|
40
|
-
}
|
|
41
|
-
</ion-buttons>
|
|
42
|
-
</ion-item>
|