@mintplayer/ng-spark 22.29.0 → 22.31.0
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/README.md +3 -3
- package/auth/README.md +216 -0
- package/fesm2022/mintplayer-ng-spark-auth-account.mjs +2023 -0
- package/fesm2022/mintplayer-ng-spark-auth-account.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-auth-auth-bar.mjs +96 -0
- package/fesm2022/mintplayer-ng-spark-auth-auth-bar.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-auth-confirm-email.mjs +200 -0
- package/fesm2022/mintplayer-ng-spark-auth-confirm-email.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-auth-core.mjs +452 -0
- package/fesm2022/mintplayer-ng-spark-auth-core.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-auth-external-login.mjs +201 -0
- package/fesm2022/mintplayer-ng-spark-auth-external-login.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-auth-forgot-password.mjs +196 -0
- package/fesm2022/mintplayer-ng-spark-auth-forgot-password.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-auth-guards.mjs +16 -0
- package/fesm2022/mintplayer-ng-spark-auth-guards.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-auth-interceptors.mjs +18 -0
- package/fesm2022/mintplayer-ng-spark-auth-interceptors.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-auth-login.mjs +282 -0
- package/fesm2022/mintplayer-ng-spark-auth-login.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-auth-models.mjs +114 -0
- package/fesm2022/mintplayer-ng-spark-auth-models.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-auth-pipes.mjs +43 -0
- package/fesm2022/mintplayer-ng-spark-auth-pipes.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-auth-register.mjs +216 -0
- package/fesm2022/mintplayer-ng-spark-auth-register.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-auth-reset-password.mjs +223 -0
- package/fesm2022/mintplayer-ng-spark-auth-reset-password.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-auth-routes.mjs +194 -0
- package/fesm2022/mintplayer-ng-spark-auth-routes.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-auth-sign-in.mjs +210 -0
- package/fesm2022/mintplayer-ng-spark-auth-sign-in.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-auth-two-factor.mjs +218 -0
- package/fesm2022/mintplayer-ng-spark-auth-two-factor.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-auth.mjs +48 -0
- package/fesm2022/mintplayer-ng-spark-auth.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-client-operations.mjs +368 -2
- package/fesm2022/mintplayer-ng-spark-client-operations.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-grid.mjs +22 -9
- package/fesm2022/mintplayer-ng-spark-grid.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-identity-provider-connected-applications.mjs +389 -0
- package/fesm2022/mintplayer-ng-spark-identity-provider-connected-applications.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-identity-provider-core.mjs +204 -0
- package/fesm2022/mintplayer-ng-spark-identity-provider-core.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-identity-provider-developers.mjs +486 -0
- package/fesm2022/mintplayer-ng-spark-identity-provider-developers.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-identity-provider-management.mjs +350 -0
- package/fesm2022/mintplayer-ng-spark-identity-provider-management.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-identity-provider.mjs +66 -0
- package/fesm2022/mintplayer-ng-spark-identity-provider.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-models.mjs +2 -1
- package/fesm2022/mintplayer-ng-spark-models.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-po-detail.mjs +13 -3
- package/fesm2022/mintplayer-ng-spark-po-detail.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-po-form.mjs +6 -3
- package/fesm2022/mintplayer-ng-spark-po-form.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-pwa.mjs +162 -0
- package/fesm2022/mintplayer-ng-spark-pwa.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-query-list.mjs +5 -2
- package/fesm2022/mintplayer-ng-spark-query-list.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-renderers.mjs +109 -4
- package/fesm2022/mintplayer-ng-spark-renderers.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs +36 -6
- package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-services.mjs +48 -6
- package/fesm2022/mintplayer-ng-spark-services.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-shell.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark.mjs.map +1 -1
- package/package.json +101 -3
- package/types/mintplayer-ng-spark-auth-account.d.ts +255 -0
- package/types/mintplayer-ng-spark-auth-auth-bar.d.ts +22 -0
- package/types/mintplayer-ng-spark-auth-confirm-email.d.ts +21 -0
- package/types/mintplayer-ng-spark-auth-core.d.ts +197 -0
- package/types/mintplayer-ng-spark-auth-external-login.d.ts +132 -0
- package/types/mintplayer-ng-spark-auth-forgot-password.d.ts +18 -0
- package/types/mintplayer-ng-spark-auth-guards.d.ts +15 -0
- package/types/mintplayer-ng-spark-auth-interceptors.d.ts +2 -0
- package/types/mintplayer-ng-spark-auth-login.d.ts +46 -0
- package/types/mintplayer-ng-spark-auth-models.d.ts +489 -0
- package/types/mintplayer-ng-spark-auth-pipes.d.ts +8 -0
- package/types/mintplayer-ng-spark-auth-register.d.ts +21 -0
- package/types/mintplayer-ng-spark-auth-reset-password.d.ts +25 -0
- package/types/mintplayer-ng-spark-auth-routes.d.ts +154 -0
- package/types/mintplayer-ng-spark-auth-sign-in.d.ts +84 -0
- package/types/mintplayer-ng-spark-auth-two-factor.d.ts +23 -0
- package/types/mintplayer-ng-spark-auth.d.ts +24 -0
- package/types/mintplayer-ng-spark-client-operations.d.ts +148 -3
- package/types/mintplayer-ng-spark-grid.d.ts +19 -1
- package/types/mintplayer-ng-spark-identity-provider-connected-applications.d.ts +35 -0
- package/types/mintplayer-ng-spark-identity-provider-core.d.ts +144 -0
- package/types/mintplayer-ng-spark-identity-provider-developers.d.ts +55 -0
- package/types/mintplayer-ng-spark-identity-provider-management.d.ts +33 -0
- package/types/mintplayer-ng-spark-identity-provider.d.ts +64 -0
- package/types/mintplayer-ng-spark-models.d.ts +28 -0
- package/types/mintplayer-ng-spark-po-detail.d.ts +8 -0
- package/types/mintplayer-ng-spark-po-form.d.ts +2 -0
- package/types/mintplayer-ng-spark-pwa.d.ts +89 -0
- package/types/mintplayer-ng-spark-query-list.d.ts +2 -0
- package/types/mintplayer-ng-spark-renderers.d.ts +47 -0
- package/types/mintplayer-ng-spark-retry-action-modal.d.ts +1 -0
- package/types/mintplayer-ng-spark-services.d.ts +37 -1
- package/types/mintplayer-ng-spark-shell.d.ts +2 -2
- package/types/mintplayer-ng-spark.d.ts +4 -4
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { SparkAccountOverviewLink, SparkAuthRouteEntries, SparkAuthRouteEntry, SparkAuthRoutePaths, SparkExternalProviderPresentation } from "@mintplayer/ng-spark/auth/models";
|
|
2
|
+
import { CanActivateFn } from "@angular/router";
|
|
3
|
+
type Loader = () => Promise<any>;
|
|
4
|
+
interface Child {
|
|
5
|
+
path: string;
|
|
6
|
+
loadComponent?: Loader;
|
|
7
|
+
canActivate?: CanActivateFn[];
|
|
8
|
+
children?: [];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The passkeys page: the generic persistent-object page of the Authorization library's virtual
|
|
12
|
+
* `Passkeys` type, one per signed-in user, so the id is the fixed `me` (generic passkeys page PRD D1).
|
|
13
|
+
*/
|
|
14
|
+
export declare const SPARK_PASSKEYS_PAGE_URL = "/po/passkeys/me";
|
|
15
|
+
/**
|
|
16
|
+
* One opt-in group of authentication pages, passed to {@link sparkAuthRoutes}. Constructed only by
|
|
17
|
+
* ng-spark's entry points: `withLocalLogin()`, `withRegistration()`, `withExternalLogin()`,
|
|
18
|
+
* `withPasskeys()` and `withAccount()` here, and `withIdentityProvider()` from
|
|
19
|
+
* `@mintplayer/ng-spark/identity-provider`. That keeps the set of mountable pages a decision this
|
|
20
|
+
* library makes rather than a shape an application invents.
|
|
21
|
+
*/
|
|
22
|
+
export interface SparkAuthRoutesFeature {
|
|
23
|
+
readonly children: Child[];
|
|
24
|
+
readonly paths: SparkAuthRoutePaths;
|
|
25
|
+
readonly providers?: SparkExternalProviderPresentation[];
|
|
26
|
+
/** Extra links for the account overview (`SPARK_ACCOUNT_OVERVIEW_LINKS`). */
|
|
27
|
+
readonly accountLinks?: SparkAccountOverviewLink[];
|
|
28
|
+
}
|
|
29
|
+
/** Path override for the sign-in landing page. Named to stay clear of the core package's
|
|
30
|
+
* `SparkExternalLoginOptions`, which is about the sign-in *call* rather than the route. */
|
|
31
|
+
export type SparkExternalLoginRouteOptions = Pick<SparkAuthRouteEntries, 'signIn'>;
|
|
32
|
+
/**
|
|
33
|
+
* The routes for Spark's authentication pages.
|
|
34
|
+
*
|
|
35
|
+
* **Nothing is mounted unless a feature asks for it.** Passing no features emits no pages at all —
|
|
36
|
+
* opt-in enforced by construction rather than by a flag, matching `provideHttpClient(withFetch())`
|
|
37
|
+
* and `provideRouter(withComponentInputBinding())`. Before this the pages mounted by default and an
|
|
38
|
+
* application had to opt *out*, so every app shipped a registration form whether or not it wanted
|
|
39
|
+
* one.
|
|
40
|
+
*
|
|
41
|
+
* ```ts
|
|
42
|
+
* sparkAuthRoutes(
|
|
43
|
+
* withLocalLogin(),
|
|
44
|
+
* withRegistration(),
|
|
45
|
+
* withExternalLogin(githubProvider(), facebookProvider()),
|
|
46
|
+
* )
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* The `import()` expressions live *inside* each feature. That placement is the point: a bundler
|
|
50
|
+
* decides whether to emit a lazy chunk from whether the `import()` call site is reachable, not from
|
|
51
|
+
* whether the route object referencing it survives — so filtering a children array after the fact
|
|
52
|
+
* would still ship every page. A page nobody opted into has no reachable `import()` at all.
|
|
53
|
+
*/
|
|
54
|
+
export declare function sparkAuthRoutes(...features: SparkAuthRoutesFeature[]): any[];
|
|
55
|
+
/**
|
|
56
|
+
* Mounts the email/password family: login, two-factor, forgot-password, reset-password.
|
|
57
|
+
*
|
|
58
|
+
* These four are one feature rather than four because they form a star centred on the login page and
|
|
59
|
+
* every template dereferences its siblings unconditionally — removing any proper subset leaves a
|
|
60
|
+
* dangling link. Registration is genuinely separable, and is its own feature.
|
|
61
|
+
*
|
|
62
|
+
* Two-factor belongs here because it is reachable only from the login page's `RequiresTwoFactor`
|
|
63
|
+
* branch and posts to the same `/login` endpoint: it is part of password sign-in, not of
|
|
64
|
+
* authentication in general.
|
|
65
|
+
*/
|
|
66
|
+
export declare function withLocalLogin(entries?: Pick<SparkAuthRouteEntries, 'login' | 'twoFactor' | 'forgotPassword' | 'resetPassword'>): SparkAuthRoutesFeature;
|
|
67
|
+
/**
|
|
68
|
+
* Mounts the self-service registration page.
|
|
69
|
+
*
|
|
70
|
+
* Separate from {@link withLocalLogin} because the two decisions genuinely are separate: an
|
|
71
|
+
* application whose accounts are provisioned by an administrator still needs password sign-in and
|
|
72
|
+
* password reset. Mount it only alongside a server whose `SparkLocalCredentials` is `Full` — with
|
|
73
|
+
* `SignInOnly` the endpoint it posts to is not mapped.
|
|
74
|
+
*/
|
|
75
|
+
export declare function withRegistration(entry?: SparkAuthRouteEntry): SparkAuthRoutesFeature;
|
|
76
|
+
/**
|
|
77
|
+
* Mounts the sign-in landing page — a button per external provider the *server* reports.
|
|
78
|
+
*
|
|
79
|
+
* Accepts provider declarations and, in any position, one options object for the page's own path;
|
|
80
|
+
* the two shapes are disjoint, so `withExternalLogin(githubProvider(), facebookProvider())` and
|
|
81
|
+
* `withExternalLogin({ signIn: 'landing' }, githubProvider())` both read naturally.
|
|
82
|
+
*
|
|
83
|
+
* Declaring no providers is valid and useful: the page still renders whatever
|
|
84
|
+
* `GET /spark/auth/capabilities` reports, using default buttons.
|
|
85
|
+
*/
|
|
86
|
+
export declare function withExternalLogin(...providersOrOptions: (SparkExternalProviderPresentation | SparkExternalLoginRouteOptions)[]): SparkAuthRoutesFeature;
|
|
87
|
+
/**
|
|
88
|
+
* Presentation for one provider's button, keyed by the scheme the server reports.
|
|
89
|
+
*
|
|
90
|
+
* The generic form. `githubProvider()` and friends are this with a scheme and an icon filled in —
|
|
91
|
+
* they exist so the common case does not require knowing the scheme string, not because the library
|
|
92
|
+
* has an opinion about which providers exist.
|
|
93
|
+
*/
|
|
94
|
+
/**
|
|
95
|
+
* Mounts the passkey management path, which forwards to the generic passkeys page (`/po/passkeys/me`).
|
|
96
|
+
*
|
|
97
|
+
* Independent of every other feature here, and of the server's `SparkLocalCredentials`: a passkey is
|
|
98
|
+
* a passwordless credential, so the applications most likely to want this page are exactly the ones
|
|
99
|
+
* that mount no password pages at all. It pairs with `SparkPasskeys.Enabled` on the server.
|
|
100
|
+
*
|
|
101
|
+
* ⚠️ The page assumes a signed-in user — enrollment adds a credential to an existing account, it
|
|
102
|
+
* cannot create one. Mount it inside the application's authenticated area, or behind
|
|
103
|
+
* `sparkAuthGuard`; the server answers the page with 404 to a visitor who is not signed in.
|
|
104
|
+
*/
|
|
105
|
+
export declare function withPasskeys(entry?: SparkAuthRouteEntry): SparkAuthRoutesFeature;
|
|
106
|
+
/** Options for {@link withAccount}: a path/component per page, and the guard of the signed-in pages. */
|
|
107
|
+
export type SparkAccountRouteOptions = Pick<SparkAuthRouteEntries, 'confirmEmail' | 'account' | 'profile' | 'changePassword' | 'twoFactorSetup' | 'externalLogins' | 'passkeys' | 'personalData'> & {
|
|
108
|
+
/**
|
|
109
|
+
* Guards the signed-in pages (everything but confirm-email). Defaults to `[sparkAuthGuard]`,
|
|
110
|
+
* which waits for the session check so a hard reload does not bounce a signed-in user to the
|
|
111
|
+
* sign-in page. Pass `[]` when the pages sit under a guarded parent route already.
|
|
112
|
+
*/
|
|
113
|
+
canActivate?: CanActivateFn[];
|
|
114
|
+
/**
|
|
115
|
+
* Pages to leave out, e.g. `['externalLogins']` for an app without external providers or
|
|
116
|
+
* `['changePassword']` under `SparkLocalCredentials.Disabled` (the endpoint is not mapped there).
|
|
117
|
+
*/
|
|
118
|
+
exclude?: (keyof Omit<SparkAccountRouteOptions, 'canActivate' | 'exclude'>)[];
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* Mounts the account pages (#460, D16), each also usable as a standalone component:
|
|
122
|
+
*
|
|
123
|
+
* | page | default path | component |
|
|
124
|
+
* |---|---|---|
|
|
125
|
+
* | confirm email (public; the mail link target) | `confirm-email` | `SparkConfirmEmailComponent` |
|
|
126
|
+
* | overview | `account` | `SparkAccountOverviewComponent` |
|
|
127
|
+
* | profile (user name, email change, mail language, app fields) | `account/profile` | `SparkAccountProfileComponent` |
|
|
128
|
+
* | change / set password | `account/password` | `SparkChangePasswordComponent` |
|
|
129
|
+
* | two-factor (authenticator, recovery codes) | `account/two-factor` | `SparkTwoFactorSetupComponent` |
|
|
130
|
+
* | connected logins | `account/logins` | `SparkExternalLoginsComponent` |
|
|
131
|
+
* | passkeys (forwards to the generic page, `/po/passkeys/me`) | `account/passkeys` | — |
|
|
132
|
+
* | personal data + account deletion | `account/personal-data` | `SparkPersonalDataComponent` |
|
|
133
|
+
*
|
|
134
|
+
* `confirm-email` must stay at the server's `Spark:Auth:Links:ConfirmEmailPath` (default
|
|
135
|
+
* `/confirm-email`), which confirmation mails link to. No path has a parameterised first segment, so the
|
|
136
|
+
* group neither shadows `sparkRoutes()` nor is shadowed by it.
|
|
137
|
+
*/
|
|
138
|
+
export declare function withAccount(options?: SparkAccountRouteOptions): SparkAuthRoutesFeature;
|
|
139
|
+
export declare function externalProvider(scheme: string, presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>): SparkExternalProviderPresentation;
|
|
140
|
+
export declare function githubProvider(presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>): SparkExternalProviderPresentation;
|
|
141
|
+
export declare function googleProvider(presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>): SparkExternalProviderPresentation;
|
|
142
|
+
export declare function facebookProvider(presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>): SparkExternalProviderPresentation;
|
|
143
|
+
export declare function microsoftProvider(presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>): SparkExternalProviderPresentation;
|
|
144
|
+
/** X (formerly Twitter) — the server's `spark.AddTwitter()` preset (OAuth 2.0), scheme `Twitter`. */
|
|
145
|
+
export declare function twitterProvider(presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>): SparkExternalProviderPresentation;
|
|
146
|
+
/** LinkedIn — the server's `spark.AddLinkedIn()` preset (OpenID Connect userinfo), scheme `LinkedIn`. */
|
|
147
|
+
export declare function linkedInProvider(presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>): SparkExternalProviderPresentation;
|
|
148
|
+
/**
|
|
149
|
+
* Any OpenID Connect provider — the client half of the server's OIDC preset
|
|
150
|
+
* (`spark.AddOpenIdConnect(...)`, or a `Spark:Auth:Providers:OpenIdConnect:<scheme>` section). Unlike the named presets the scheme is the
|
|
151
|
+
* application's own choice, so it and the button text are required; `scheme` must equal the server's
|
|
152
|
+
* scheme name exactly.
|
|
153
|
+
*/
|
|
154
|
+
export declare function oidcProvider(scheme: string, displayName: string, iconClass?: string): SparkExternalProviderPresentation;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import { TemplateRef } from "@angular/core";
|
|
3
|
+
import { Color } from "@mintplayer/ng-bootstrap";
|
|
4
|
+
import { SparkExternalProviderView, SparkProviderButtonContext, SparkProviderButtonContext as SparkProviderButtonContext$1 } from "@mintplayer/ng-spark/auth/external-login";
|
|
5
|
+
/**
|
|
6
|
+
* The sign-in landing page: a button per external provider, and a link to the password form when the
|
|
7
|
+
* application mounted one.
|
|
8
|
+
*
|
|
9
|
+
* The provider buttons are `<spark-external-login-buttons>`, which the login page hosts as well; this
|
|
10
|
+
* page adds the passkey button, the link to the password form, and says so when there is no way to
|
|
11
|
+
* sign in at all.
|
|
12
|
+
*/
|
|
13
|
+
export declare class SparkSignInComponent {
|
|
14
|
+
private readonly authService;
|
|
15
|
+
private readonly route;
|
|
16
|
+
private readonly router;
|
|
17
|
+
private readonly config;
|
|
18
|
+
readonly routePaths: Partial<Record<keyof import("@mintplayer/ng-spark/auth/models").SparkAuthRouteEntries, string>>;
|
|
19
|
+
readonly colors: typeof Color;
|
|
20
|
+
/**
|
|
21
|
+
* Where to land after a successful external sign-in.
|
|
22
|
+
*
|
|
23
|
+
* Falls back to a `?returnUrl=` query parameter, matching what the login page already does — so a
|
|
24
|
+
* plain `<a routerLink="/sign-in" [queryParams]="{ returnUrl: '/somewhere' }">` works with no
|
|
25
|
+
* wiring, which is what a routed page needs since the router passes it no inputs. The query value
|
|
26
|
+
* is validated as a local path before use; an off-site one is dropped rather than followed.
|
|
27
|
+
*/
|
|
28
|
+
readonly returnUrl: import("@angular/core").InputSignal<string | undefined>;
|
|
29
|
+
private effectiveReturnUrl;
|
|
30
|
+
/**
|
|
31
|
+
* Replaces the default provider button. Rendered once per provider with a
|
|
32
|
+
* {@link SparkProviderButtonContext}.
|
|
33
|
+
*
|
|
34
|
+
* Reachable only when the consumer *hosts* this component — the router instantiates it with no
|
|
35
|
+
* projected content, so on a default `withExternalLogin()` route there is nothing to project into.
|
|
36
|
+
* Host it via `withExternalLogin({ signIn: { path: 'sign-in', component: MySignIn } })` and pass
|
|
37
|
+
* the template from there.
|
|
38
|
+
*/
|
|
39
|
+
readonly providerTemplate: import("@angular/core").InputSignal<TemplateRef<SparkProviderButtonContext$1> | null>;
|
|
40
|
+
/** Whether the server reported any external provider; with none and no passkeys there is no way in. */
|
|
41
|
+
readonly hasProviders: import("@angular/core").WritableSignal<boolean>;
|
|
42
|
+
readonly localCredentialsAvailable: import("@angular/core").WritableSignal<boolean>;
|
|
43
|
+
readonly loading: import("@angular/core").WritableSignal<boolean>;
|
|
44
|
+
readonly failed: import("@angular/core").WritableSignal<boolean>;
|
|
45
|
+
/**
|
|
46
|
+
* Two conditions, and both are necessary. The server must have mounted the sign-in endpoint, and
|
|
47
|
+
* this browser must be able to run the ceremony — offering the button on either half alone
|
|
48
|
+
* produces a control that fails the moment it is clicked.
|
|
49
|
+
*/
|
|
50
|
+
readonly passkeysAvailable: import("@angular/core").WritableSignal<boolean>;
|
|
51
|
+
readonly passkeyBusy: import("@angular/core").WritableSignal<boolean>;
|
|
52
|
+
readonly passkeyError: import("@angular/core").WritableSignal<string>;
|
|
53
|
+
constructor();
|
|
54
|
+
private load;
|
|
55
|
+
/**
|
|
56
|
+
* The routes are a build-time decision and the server's mode a deployment-time one, so they can
|
|
57
|
+
* disagree without anything failing loudly. Reaching this page at all means the app routed it,
|
|
58
|
+
* which it only does when local credentials are meant to be limited.
|
|
59
|
+
*/
|
|
60
|
+
private warnOnMismatch;
|
|
61
|
+
/**
|
|
62
|
+
* Signs in with a passkey, then navigates. The navigation matters for the same reason it does
|
|
63
|
+
* after an external sign-in: nothing else moves the user off this page.
|
|
64
|
+
*
|
|
65
|
+
* No username is collected, and none should be: the server's request-options endpoint refuses to
|
|
66
|
+
* accept an identity so that its answer cannot reveal whether an account exists. The browser
|
|
67
|
+
* offers whatever discoverable credential it holds.
|
|
68
|
+
*/
|
|
69
|
+
signInWithPasskey(): Promise<void>;
|
|
70
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SparkSignInComponent, never>;
|
|
71
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SparkSignInComponent, "spark-sign-in", never, {
|
|
72
|
+
"returnUrl": {
|
|
73
|
+
"alias": "returnUrl";
|
|
74
|
+
"required": false;
|
|
75
|
+
"isSignal": true;
|
|
76
|
+
};
|
|
77
|
+
"providerTemplate": {
|
|
78
|
+
"alias": "providerTemplate";
|
|
79
|
+
"required": false;
|
|
80
|
+
"isSignal": true;
|
|
81
|
+
};
|
|
82
|
+
}, {}, never, never, true, never>;
|
|
83
|
+
}
|
|
84
|
+
export type { SparkExternalProviderView, SparkProviderButtonContext };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Color } from "@mintplayer/ng-bootstrap";
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export declare class SparkTwoFactorComponent {
|
|
4
|
+
private readonly fb;
|
|
5
|
+
private readonly authService;
|
|
6
|
+
private readonly router;
|
|
7
|
+
private readonly route;
|
|
8
|
+
private readonly config;
|
|
9
|
+
private readonly translation;
|
|
10
|
+
readonly routePaths: Partial<Record<keyof import("@mintplayer/ng-spark/auth/models").SparkAuthRouteEntries, string>>;
|
|
11
|
+
colors: typeof Color;
|
|
12
|
+
readonly loading: import("@angular/core").WritableSignal<boolean>;
|
|
13
|
+
readonly errorMessage: import("@angular/core").WritableSignal<string>;
|
|
14
|
+
readonly useRecoveryCode: import("@angular/core").WritableSignal<boolean>;
|
|
15
|
+
readonly form: import("@angular/forms").FormGroup<{
|
|
16
|
+
code: import("@angular/forms").FormControl<string | null>;
|
|
17
|
+
recoveryCode: import("@angular/forms").FormControl<string | null>;
|
|
18
|
+
}>;
|
|
19
|
+
toggleRecoveryCode(): void;
|
|
20
|
+
onSubmit(): Promise<void>;
|
|
21
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SparkTwoFactorComponent, never>;
|
|
22
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SparkTwoFactorComponent, "spark-two-factor", never, {}, {}, never, never, true, never>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { SPARK_AUTH_CONFIG, SparkAuthConfig, SparkAuthConfig as SparkAuthConfig$1, defaultSparkAuthConfig } from "@mintplayer/ng-spark/auth/models";
|
|
2
|
+
import { EnvironmentProviders } from "@angular/core";
|
|
3
|
+
import { HttpFeature, HttpFeatureKind } from "@angular/common/http";
|
|
4
|
+
import { SparkClientMethodMap } from "@mintplayer/ng-spark/client-operations";
|
|
5
|
+
export declare function provideSparkAuth(config?: Partial<SparkAuthConfig$1>): EnvironmentProviders;
|
|
6
|
+
export declare function withSparkAuth(): HttpFeature<HttpFeatureKind>[];
|
|
7
|
+
/**
|
|
8
|
+
* The browser steps the Authorization library's server actions invoke (`IRetryAccessor.Invoke`),
|
|
9
|
+
* registered by {@link provideSparkAuth}.
|
|
10
|
+
*
|
|
11
|
+
* `webauthn.create` is the enrollment ceremony of the passkeys page's `AddPasskey` action: the
|
|
12
|
+
* server hands it the creation options and receives the credential back in the same action, which
|
|
13
|
+
* attests it against the ceremony cookie its first pass set. The server keeps the challenge; nothing
|
|
14
|
+
* here chooses or carries one.
|
|
15
|
+
*
|
|
16
|
+
* - The user dismissing the prompt (`cancelled`, `no_credential`) rejects, which answers the server
|
|
17
|
+
* with `Cancel`: not an error, so no banner.
|
|
18
|
+
* - Any other failure (an authenticator already holding a credential for this account, a security
|
|
19
|
+
* error) resolves as `{ error }`, so the server can say it did not work.
|
|
20
|
+
* - An unsupported browser never runs it (`supported`), and the action shows disabled with
|
|
21
|
+
* `auth.passkeyUnsupported` as the reason.
|
|
22
|
+
*/
|
|
23
|
+
export declare const sparkAuthClientMethods: SparkClientMethodMap;
|
|
24
|
+
export { SPARK_AUTH_CONFIG, type SparkAuthConfig, defaultSparkAuthConfig };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { PersistentObject, TranslatedString } from "@mintplayer/ng-spark/models";
|
|
2
2
|
import * as i0 from "@angular/core";
|
|
3
3
|
import { EnvironmentProviders, InjectionToken } from "@angular/core";
|
|
4
|
+
import { Color } from "@mintplayer/ng-bootstrap";
|
|
4
5
|
export declare enum NotificationKind {
|
|
5
6
|
Info = 0,
|
|
6
7
|
Success = 1,
|
|
@@ -53,13 +54,34 @@ export interface RetryOperation {
|
|
|
53
54
|
defaultOption?: string | null;
|
|
54
55
|
persistentObject?: PersistentObject | null;
|
|
55
56
|
message?: string | null;
|
|
57
|
+
/** Whether the client offers its own translated Cancel, answered as `'Cancel'` (`IRetryAccessor.Action(..., cancellable)`). */
|
|
58
|
+
cancellable?: boolean;
|
|
59
|
+
/** A client method to run instead of a modal (`IRetryAccessor.Invoke`); see `provideSparkClientMethods`. */
|
|
60
|
+
clientMethod?: string | null;
|
|
61
|
+
/** Its argument, as the server serialized it. */
|
|
62
|
+
arguments?: unknown;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* A value the server shows exactly once (a generated client secret, an API token), in a dialog with
|
|
66
|
+
* a copy button (`IClientAccessor.ShowSecret`, `docs/identity_provider_platform_PRD.md` D5). The server
|
|
67
|
+
* keeps only a hash. The value is never written to the page's state, the URL or browser storage, and
|
|
68
|
+
* closing the dialog discards it.
|
|
69
|
+
*/
|
|
70
|
+
export interface ShowSecretOperation {
|
|
71
|
+
type: 'showSecret';
|
|
72
|
+
/** The dialog's title, in the request's language. */
|
|
73
|
+
title: string;
|
|
74
|
+
/** The explanation shown above the value, in the request's language. */
|
|
75
|
+
message: string;
|
|
76
|
+
/** The value itself. */
|
|
77
|
+
value: string;
|
|
56
78
|
}
|
|
57
79
|
/**
|
|
58
80
|
* Discriminated union of known operation types, plus an open shape for unknown
|
|
59
81
|
* future operations. Handlers should narrow via the `type` discriminator before
|
|
60
82
|
* accessing fields specific to their operation type.
|
|
61
83
|
*/
|
|
62
|
-
export type ClientOperation = NavigateOperation | NotifyOperation | RefreshAttributeOperation | RefreshQueryOperation | RetryOperation | {
|
|
84
|
+
export type ClientOperation = NavigateOperation | NotifyOperation | RefreshAttributeOperation | RefreshQueryOperation | RetryOperation | ShowSecretOperation | {
|
|
63
85
|
type: string;
|
|
64
86
|
[key: string]: unknown;
|
|
65
87
|
};
|
|
@@ -85,7 +107,7 @@ export interface ClientOperationEnvelope<T = unknown> {
|
|
|
85
107
|
* The dispatcher treats handler resolution as allow-list-by-type (unknown
|
|
86
108
|
* types drop). It does NOT validate the *content* of each operation. Handlers
|
|
87
109
|
* that act on URL-shaped fields (navigate, redirect, openWindow) MUST run
|
|
88
|
-
* the value through `sanitizeReturnUrl` from `@mintplayer/ng-spark
|
|
110
|
+
* the value through `sanitizeReturnUrl` from `@mintplayer/ng-spark/auth/models`
|
|
89
111
|
* (or an equivalent same-origin check) before acting on it. Otherwise a
|
|
90
112
|
* single attribute-echo XSS or a single mid-channel byte flip on a non-TLS
|
|
91
113
|
* path lets the server drive client navigation to an attacker host. The
|
|
@@ -120,6 +142,70 @@ export interface ClientOperationHandlerRegistration {
|
|
|
120
142
|
* providers using this token.
|
|
121
143
|
*/
|
|
122
144
|
export declare const SPARK_CLIENT_OPERATION_HANDLERS: InjectionToken<readonly ClientOperationHandlerRegistration[]>;
|
|
145
|
+
/**
|
|
146
|
+
* One step a server action needs from the browser (`IRetryAccessor.Invoke` on the server): WebAuthn,
|
|
147
|
+
* a file picker, the clipboard. The answer travels back into the same server action as the retry's
|
|
148
|
+
* `value`, so authorization, state and the follow-up all stay inside that one action.
|
|
149
|
+
*/
|
|
150
|
+
export interface SparkClientMethod {
|
|
151
|
+
/**
|
|
152
|
+
* Runs the step. Called in an injection context, so `inject()` works synchronously at the top.
|
|
153
|
+
* A rejection or a thrown error answers the server with `Cancel`, exactly like an unknown name.
|
|
154
|
+
*/
|
|
155
|
+
invoke(args: unknown): Promise<unknown>;
|
|
156
|
+
/**
|
|
157
|
+
* Whether this browser can run the method at all. An action whose `requiresClient` names a method
|
|
158
|
+
* that is unsupported is shown disabled; an `Invoke` of it answers `Cancel` without running it.
|
|
159
|
+
* Absent means always supported.
|
|
160
|
+
*/
|
|
161
|
+
supported?(): boolean;
|
|
162
|
+
/** The translation key explaining why the method is unsupported; defaults to `common.clientUnsupported`. */
|
|
163
|
+
unsupportedReason?: string;
|
|
164
|
+
}
|
|
165
|
+
/** Client methods by the name the server invokes them with, e.g. `{ 'webauthn.create': { invoke: … } }`. */
|
|
166
|
+
export type SparkClientMethodMap = Readonly<Record<string, SparkClientMethod>>;
|
|
167
|
+
/** Multi-provider token; use {@link provideSparkClientMethods}. A later registration of a name wins. */
|
|
168
|
+
export declare const SPARK_CLIENT_METHODS: InjectionToken<readonly Readonly<Record<string, SparkClientMethod>>[]>;
|
|
169
|
+
/** The reason shown on an action whose client method is missing or unsupported, when the method names none. */
|
|
170
|
+
export declare const SPARK_CLIENT_UNSUPPORTED_REASON = "common.clientUnsupported";
|
|
171
|
+
/**
|
|
172
|
+
* Registers client methods a server action may invoke through a retry (`IRetryAccessor.Invoke`).
|
|
173
|
+
*
|
|
174
|
+
* The set is closed on purpose: the server can only name a method the app registered here, and an
|
|
175
|
+
* unknown name answers `Cancel`. Nothing the server sends is evaluated.
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* provideSparkClientMethods({
|
|
179
|
+
* 'clipboard.read': { invoke: () => navigator.clipboard.readText(), supported: () => !!navigator.clipboard },
|
|
180
|
+
* })
|
|
181
|
+
*/
|
|
182
|
+
export declare function provideSparkClientMethods(methods: SparkClientMethodMap): EnvironmentProviders;
|
|
183
|
+
/** How a client method ended: its value, or a failure the server sees as `Cancel`. */
|
|
184
|
+
export type SparkClientMethodOutcome = {
|
|
185
|
+
ok: true;
|
|
186
|
+
value: unknown;
|
|
187
|
+
} | {
|
|
188
|
+
ok: false;
|
|
189
|
+
};
|
|
190
|
+
/** The registered client methods: whether one can run here, and running it. */
|
|
191
|
+
export declare class SparkClientMethodRegistry {
|
|
192
|
+
private readonly injector;
|
|
193
|
+
private readonly methods;
|
|
194
|
+
constructor();
|
|
195
|
+
/**
|
|
196
|
+
* Null when the method is registered and supported here; otherwise the translation key saying why
|
|
197
|
+
* it is not. Null for no name at all, so an action without `requiresClient` is never affected.
|
|
198
|
+
*/
|
|
199
|
+
unavailableReason(name: string | null | undefined): string | null;
|
|
200
|
+
/**
|
|
201
|
+
* Runs the method registered under `name`. Fails closed: an unknown name, an unsupported method, a
|
|
202
|
+
* rejection or a thrown error all end as `{ ok: false }`, which the retry loop answers as `Cancel`.
|
|
203
|
+
*/
|
|
204
|
+
invoke(name: string, args: unknown): Promise<SparkClientMethodOutcome>;
|
|
205
|
+
private isSupported;
|
|
206
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SparkClientMethodRegistry, never>;
|
|
207
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<any>;
|
|
208
|
+
}
|
|
123
209
|
export interface SparkToast {
|
|
124
210
|
id: string;
|
|
125
211
|
message: string;
|
|
@@ -150,7 +236,10 @@ export declare class SparkToastContainerComponent {
|
|
|
150
236
|
}
|
|
151
237
|
/**
|
|
152
238
|
* Registers the built-in client-operation handlers: `notify`, `refreshQuery`,
|
|
153
|
-
* `refreshAttribute` and `
|
|
239
|
+
* `refreshAttribute`, `navigate` and `showSecret`. Apps add this once in their bootstrap providers.
|
|
240
|
+
*
|
|
241
|
+
* `showSecret` opens {@link SparkSecretDialogService}'s dialog, which mounts itself: without it the
|
|
242
|
+
* value the server shows once (a client secret, a token) would be lost, since the server keeps a hash.
|
|
154
243
|
*
|
|
155
244
|
* Unregistered operation types are dropped SILENTLY by the dispatcher, which is why
|
|
156
245
|
* `refreshQuery` did nothing at all for as long as it went unhandled — the server emitted
|
|
@@ -170,6 +259,62 @@ export declare class SparkToastContainerComponent {
|
|
|
170
259
|
* `multi: true` providers using <see cref="SPARK_CLIENT_OPERATION_HANDLERS" />.
|
|
171
260
|
*/
|
|
172
261
|
export declare function provideSparkClientOperations(): EnvironmentProviders;
|
|
262
|
+
/** A value shown once: the `showSecret` operation's payload, or a value a page received itself. */
|
|
263
|
+
export interface SparkSecret {
|
|
264
|
+
title: string;
|
|
265
|
+
message: string;
|
|
266
|
+
value: string;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Shows a value the server will never show again, in a modal with a copy button (`showSecret`,
|
|
270
|
+
* `docs/identity_provider_platform_PRD.md` D5).
|
|
271
|
+
*
|
|
272
|
+
* The dialog mounts itself on `document.body` the first time it is needed, so an application does not
|
|
273
|
+
* have to place a component in its root template for `IClientAccessor.ShowSecret` to work: a handler
|
|
274
|
+
* whose dialog nobody placed would lose the value as surely as a missing handler.
|
|
275
|
+
*
|
|
276
|
+
* The value lives only in this service's signal while the dialog is open. Closing the dialog clears
|
|
277
|
+
* it; it is never written to the URL, the router state or browser storage.
|
|
278
|
+
*/
|
|
279
|
+
export declare class SparkSecretDialogService {
|
|
280
|
+
private readonly appRef;
|
|
281
|
+
private readonly injector;
|
|
282
|
+
private readonly document;
|
|
283
|
+
private readonly browser;
|
|
284
|
+
private readonly current;
|
|
285
|
+
private dialog;
|
|
286
|
+
/** The secret on display, or null when the dialog is closed. */
|
|
287
|
+
readonly secret: import("@angular/core").Signal<SparkSecret | null>;
|
|
288
|
+
constructor();
|
|
289
|
+
show(secret: SparkSecret): void;
|
|
290
|
+
/** Closes the dialog and discards the value. */
|
|
291
|
+
close(): void;
|
|
292
|
+
private mount;
|
|
293
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SparkSecretDialogService, never>;
|
|
294
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<any>;
|
|
295
|
+
}
|
|
296
|
+
/** The dialog behind {@link SparkSecretDialogService}; mounted by the service, not by applications. */
|
|
297
|
+
export declare class SparkShowSecretModalComponent {
|
|
298
|
+
private readonly dialog;
|
|
299
|
+
private readonly document;
|
|
300
|
+
private copiedTimer;
|
|
301
|
+
protected readonly colors: typeof Color;
|
|
302
|
+
protected readonly secret: import("@angular/core").Signal<SparkSecret | null>;
|
|
303
|
+
protected readonly isOpen: import("@angular/core").Signal<boolean>;
|
|
304
|
+
protected readonly copyState: import("@angular/core").WritableSignal<"copied" | "idle" | "failed">;
|
|
305
|
+
protected readonly text: import("@angular/core").Signal<{
|
|
306
|
+
copy: string;
|
|
307
|
+
copied: string;
|
|
308
|
+
copyFailed: string;
|
|
309
|
+
close: string;
|
|
310
|
+
value: string;
|
|
311
|
+
}>;
|
|
312
|
+
protected selectAll(event: Event): void;
|
|
313
|
+
protected copy(): Promise<void>;
|
|
314
|
+
protected close(): void;
|
|
315
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SparkShowSecretModalComponent, never>;
|
|
316
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SparkShowSecretModalComponent, "spark-show-secret-modal", never, {}, {}, never, never, true, never>;
|
|
317
|
+
}
|
|
173
318
|
/**
|
|
174
319
|
* Carries a server-issued `refreshQuery` to whichever grids are showing that query.
|
|
175
320
|
*
|
|
@@ -252,6 +252,7 @@ export declare class SparkQueryGridComponent {
|
|
|
252
252
|
/** Add-on row-menu entries (`SPARK_QUERY_ROW_ACTIONS`), e.g. Contributions' revert. */
|
|
253
253
|
private readonly addonRowActions;
|
|
254
254
|
readonly lang: SparkLanguageService;
|
|
255
|
+
private readonly clientMethods;
|
|
255
256
|
/** Query alias or id. */
|
|
256
257
|
queryId: import("@angular/core").InputSignal<string>;
|
|
257
258
|
/**
|
|
@@ -549,6 +550,13 @@ export declare class SparkQueryGridComponent {
|
|
|
549
550
|
* Every column that ships is drawn (#264): there is no shipped-but-hidden column.
|
|
550
551
|
*/
|
|
551
552
|
allColumns: import("@angular/core").Signal<QueryColumn[]>;
|
|
553
|
+
/** The internal name of the per-row ⋮ menu's column; never shown or announced (its `label` is "Actions"). */
|
|
554
|
+
readonly rowActionsColumn = "__sparkRowActions";
|
|
555
|
+
/**
|
|
556
|
+
* The datatable's `[labels]`: the resize handle and its options dialog, translated. The column
|
|
557
|
+
* each string names comes from `bsDatatableColumnLabel` in the template. See `sparkDatatableLabels`.
|
|
558
|
+
*/
|
|
559
|
+
datatableLabels: import("@angular/core").Signal<import("@mintplayer/ng-spark/services").SparkDatatableLabels>;
|
|
552
560
|
/**
|
|
553
561
|
* True when rows do not come from this component's own fetch.
|
|
554
562
|
*
|
|
@@ -559,8 +567,16 @@ export declare class SparkQueryGridComponent {
|
|
|
559
567
|
* before the host had anything to bind.
|
|
560
568
|
*/
|
|
561
569
|
hasExternalData: import("@angular/core").Signal<boolean>;
|
|
562
|
-
/**
|
|
570
|
+
/**
|
|
571
|
+
* Whether an action can run right now: its selection rule is satisfied, and the client method it
|
|
572
|
+
* requires (`requiresClient`) is registered and supported here. The server checks the rule again.
|
|
573
|
+
*/
|
|
563
574
|
isActionEnabled(action: CustomActionDefinition): boolean;
|
|
575
|
+
/**
|
|
576
|
+
* Why an action is disabled regardless of the selection, translated, for its tooltip: its required
|
|
577
|
+
* client method is missing or unsupported in this browser (Q9). Null when nothing stands in the way.
|
|
578
|
+
*/
|
|
579
|
+
actionUnavailableReason(action: CustomActionDefinition): string | null;
|
|
564
580
|
constructor();
|
|
565
581
|
/**
|
|
566
582
|
* Re-run the query, keeping the current page, sort and scroll position.
|
|
@@ -872,6 +888,8 @@ export declare class SparkQueryCardComponent {
|
|
|
872
888
|
protected readonly toolbarActions: import("@angular/core").Signal<SparkQueryToolbarAction[]>;
|
|
873
889
|
protected actionClass(action: SparkQueryToolbarAction): string;
|
|
874
890
|
protected isEnabled(action: SparkQueryToolbarAction): boolean;
|
|
891
|
+
/** The tooltip of an action disabled for want of its client method (`requiresClient`); null otherwise. */
|
|
892
|
+
protected unavailableReason(action: SparkQueryToolbarAction): string | null;
|
|
875
893
|
protected run(action: SparkQueryToolbarAction): void;
|
|
876
894
|
protected readonly selection: import("@angular/core").Signal<QueryResultItem[]>;
|
|
877
895
|
static ɵfac: i0.ɵɵFactoryDeclaration<SparkQueryCardComponent, never>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Color } from "@mintplayer/ng-bootstrap";
|
|
2
|
+
import { SparkConnectedApplication, SparkConnectedScope } from "@mintplayer/ng-spark/identity-provider/core";
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* The signed-in user's connected applications (`account/applications`, PRD D6/D7): each application
|
|
6
|
+
* the user granted access to, with its logo, publisher, the granted scopes and the dates. The user
|
|
7
|
+
* withdraws the whole grant, or unticks individual scopes and withdraws only those. Required scopes
|
|
8
|
+
* (`openid`, and those the application or resource marks required) go only with the whole grant.
|
|
9
|
+
*
|
|
10
|
+
* The server resolves the scope texts in the request's language; the `spark-lang` cookie
|
|
11
|
+
* `SparkLanguageService` writes is what makes that the language the user picked here.
|
|
12
|
+
*/
|
|
13
|
+
export declare class SparkConnectedApplicationsComponent {
|
|
14
|
+
private readonly text;
|
|
15
|
+
private readonly portal;
|
|
16
|
+
protected readonly colors: typeof Color;
|
|
17
|
+
readonly loading: import("@angular/core").WritableSignal<boolean>;
|
|
18
|
+
readonly busy: import("@angular/core").WritableSignal<boolean>;
|
|
19
|
+
readonly apps: import("@angular/core").WritableSignal<SparkConnectedApplication[]>;
|
|
20
|
+
readonly error: import("@angular/core").WritableSignal<string>;
|
|
21
|
+
readonly notice: import("@angular/core").WritableSignal<string>;
|
|
22
|
+
/** Per application, the scopes the user unticked (to withdraw). */
|
|
23
|
+
private readonly unticked;
|
|
24
|
+
constructor();
|
|
25
|
+
load(): Promise<void>;
|
|
26
|
+
protected hasOptionalScopes(app: SparkConnectedApplication): boolean;
|
|
27
|
+
protected isUnticked(app: SparkConnectedApplication, scope: SparkConnectedScope): boolean;
|
|
28
|
+
protected untickedOf(app: SparkConnectedApplication): readonly string[];
|
|
29
|
+
protected setTicked(app: SparkConnectedApplication, scope: SparkConnectedScope, ticked: boolean): void;
|
|
30
|
+
withdrawUnticked(app: SparkConnectedApplication): Promise<void>;
|
|
31
|
+
withdrawAll(app: SparkConnectedApplication): Promise<void>;
|
|
32
|
+
private withdraw;
|
|
33
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SparkConnectedApplicationsComponent, never>;
|
|
34
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SparkConnectedApplicationsComponent, "spark-connected-applications", never, {}, {}, never, never, true, never>;
|
|
35
|
+
}
|