@mintplayer/ng-spark 22.34.0 → 22.35.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/fesm2022/mintplayer-ng-spark-auth-account.mjs +576 -2
- package/fesm2022/mintplayer-ng-spark-auth-account.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-auth-core.mjs +24 -0
- package/fesm2022/mintplayer-ng-spark-auth-core.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-auth-models.mjs +4 -1
- package/fesm2022/mintplayer-ng-spark-auth-models.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-auth-register.mjs +18 -5
- package/fesm2022/mintplayer-ng-spark-auth-register.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-auth-routes.mjs +22 -1
- package/fesm2022/mintplayer-ng-spark-auth-routes.mjs.map +1 -1
- package/package.json +1 -1
- package/types/mintplayer-ng-spark-auth-account.d.ts +56 -1
- package/types/mintplayer-ng-spark-auth-core.d.ts +11 -1
- package/types/mintplayer-ng-spark-auth-models.d.ts +96 -1
- package/types/mintplayer-ng-spark-auth-register.d.ts +13 -0
- package/types/mintplayer-ng-spark-auth-routes.d.ts +15 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mintplayer-ng-spark-auth-routes.mjs","names":[],"sources":["../../auth/routes/src/spark-auth-routes.ts"],"sourcesContent":["import {\n SPARK_ACCOUNT_OVERVIEW_LINKS,\n SPARK_AUTH_ROUTE_PATHS,\n SPARK_EXTERNAL_PROVIDERS,\n SparkAccountOverviewLink,\n SparkAuthRouteEntries,\n SparkAuthRouteEntry,\n SparkAuthRoutePaths,\n SparkExternalProviderPresentation,\n} from '@mintplayer/ng-spark/auth/models';\n\nimport { inject } from '@angular/core';\nimport { Router, type CanActivateFn } from '@angular/router';\nimport { sparkAuthGuard } from '@mintplayer/ng-spark/auth/guards';\n\ntype Loader = () => Promise<any>;\n\ninterface Child {\n path: string;\n loadComponent?: Loader;\n canActivate?: CanActivateFn[];\n children?: [];\n}\n\n/**\n * The passkeys page: the generic persistent-object page of the Authorization library's virtual\n * `Passkeys` type, one per signed-in user, so the id is the fixed `me` (generic passkeys page PRD D1).\n */\nexport const SPARK_PASSKEYS_PAGE_URL = '/po/passkeys/me';\n\n/** Forwards to {@link SPARK_PASSKEYS_PAGE_URL}. */\nconst toPasskeysPage: CanActivateFn = () => inject(Router).parseUrl(SPARK_PASSKEYS_PAGE_URL);\n\n/**\n * The passkeys path: a redirect into the generic page, kept for bookmarks and the account overview's\n * link (PRD D8). A guard rather than `redirectTo`, because Angular refuses `canActivate` beside\n * `redirectTo` and the sign-in guard must still run first: the router acts on the first guard in\n * array order that does not pass, so an anonymous visitor is sent to sign in, not to a 404. An\n * application that supplies its own component for the entry keeps it.\n */\nfunction passkeysChild(entry: SparkAuthRouteEntry | undefined, path: string, guard: CanActivateFn[]): Child {\n if (typeof entry === 'object' && entry.component) {\n const component = entry.component;\n return { path, loadComponent: () => Promise.resolve(component), ...(guard.length ? { canActivate: guard } : {}) };\n }\n return { path, canActivate: [...guard, toPasskeysPage], children: [] };\n}\n\n/** The routed path for an entry, independent of how its component is loaded. */\nfunction entryPath(entry: SparkAuthRouteEntry | undefined, defaultPath: string): string {\n if (entry === undefined) return defaultPath;\n return typeof entry === 'string' ? entry : entry.path;\n}\n\n/** An explicitly supplied component wins over the library's lazy import. */\nfunction child(entry: SparkAuthRouteEntry | undefined, path: string, defaultLoader: Loader): Child {\n const component = typeof entry === 'object' && entry.component ? entry.component : undefined;\n return { path, loadComponent: component ? () => Promise.resolve(component) : defaultLoader };\n}\n\n/**\n * One opt-in group of authentication pages, passed to {@link sparkAuthRoutes}. Constructed only by\n * ng-spark's entry points: `withLocalLogin()`, `withRegistration()`, `withExternalLogin()`,\n * `withPasskeys()` and `withAccount()` here, and `withIdentityProvider()` from\n * `@mintplayer/ng-spark/identity-provider`. That keeps the set of mountable pages a decision this\n * library makes rather than a shape an application invents.\n */\nexport interface SparkAuthRoutesFeature {\n readonly children: Child[];\n readonly paths: SparkAuthRoutePaths;\n readonly providers?: SparkExternalProviderPresentation[];\n /** Extra links for the account overview (`SPARK_ACCOUNT_OVERVIEW_LINKS`). */\n readonly accountLinks?: SparkAccountOverviewLink[];\n}\n\n/** Path override for the sign-in landing page. Named to stay clear of the core package's\n * `SparkExternalLoginOptions`, which is about the sign-in *call* rather than the route. */\nexport type SparkExternalLoginRouteOptions = Pick<SparkAuthRouteEntries, 'signIn'>;\n\n/**\n * The routes for Spark's authentication pages.\n *\n * **Nothing is mounted unless a feature asks for it.** Passing no features emits no pages at all —\n * opt-in enforced by construction rather than by a flag, matching `provideHttpClient(withFetch())`\n * and `provideRouter(withComponentInputBinding())`. Before this the pages mounted by default and an\n * application had to opt *out*, so every app shipped a registration form whether or not it wanted\n * one.\n *\n * ```ts\n * sparkAuthRoutes(\n * withLocalLogin(),\n * withRegistration(),\n * withExternalLogin(githubProvider(), facebookProvider()),\n * )\n * ```\n *\n * The `import()` expressions live *inside* each feature. That placement is the point: a bundler\n * decides whether to emit a lazy chunk from whether the `import()` call site is reachable, not from\n * whether the route object referencing it survives — so filtering a children array after the fact\n * would still ship every page. A page nobody opted into has no reachable `import()` at all.\n */\nexport function sparkAuthRoutes(...features: SparkAuthRoutesFeature[]): any[] {\n const children: Child[] = [];\n const paths: SparkAuthRoutePaths = {};\n const externalProviders: SparkExternalProviderPresentation[] = [];\n const accountLinks: SparkAccountOverviewLink[] = [];\n\n for (const feature of features) {\n children.push(...feature.children);\n Object.assign(paths, feature.paths);\n if (feature.providers) externalProviders.push(...feature.providers);\n if (feature.accountLinks) accountLinks.push(...feature.accountLinks);\n }\n\n return [\n {\n path: '',\n providers: [\n { provide: SPARK_AUTH_ROUTE_PATHS, useValue: paths },\n { provide: SPARK_EXTERNAL_PROVIDERS, useValue: externalProviders },\n { provide: SPARK_ACCOUNT_OVERVIEW_LINKS, useValue: accountLinks },\n ],\n children,\n },\n ];\n}\n\n/**\n * Mounts the email/password family: login, two-factor, forgot-password, reset-password.\n *\n * These four are one feature rather than four because they form a star centred on the login page and\n * every template dereferences its siblings unconditionally — removing any proper subset leaves a\n * dangling link. Registration is genuinely separable, and is its own feature.\n *\n * Two-factor belongs here because it is reachable only from the login page's `RequiresTwoFactor`\n * branch and posts to the same `/login` endpoint: it is part of password sign-in, not of\n * authentication in general.\n */\nexport function withLocalLogin(\n entries?: Pick<SparkAuthRouteEntries, 'login' | 'twoFactor' | 'forgotPassword' | 'resetPassword'>,\n): SparkAuthRoutesFeature {\n const login = entryPath(entries?.login, 'login');\n const twoFactor = entryPath(entries?.twoFactor, 'login/two-factor');\n const forgotPassword = entryPath(entries?.forgotPassword, 'forgot-password');\n const resetPassword = entryPath(entries?.resetPassword, 'reset-password');\n\n return {\n paths: {\n login: '/' + login,\n twoFactor: '/' + twoFactor,\n forgotPassword: '/' + forgotPassword,\n resetPassword: '/' + resetPassword,\n },\n children: [\n child(entries?.login, login,\n () => import('@mintplayer/ng-spark/auth/login').then(m => m.SparkLoginComponent)),\n child(entries?.twoFactor, twoFactor,\n () => import('@mintplayer/ng-spark/auth/two-factor').then(m => m.SparkTwoFactorComponent)),\n child(entries?.forgotPassword, forgotPassword,\n () => import('@mintplayer/ng-spark/auth/forgot-password').then(m => m.SparkForgotPasswordComponent)),\n child(entries?.resetPassword, resetPassword,\n () => import('@mintplayer/ng-spark/auth/reset-password').then(m => m.SparkResetPasswordComponent)),\n ],\n };\n}\n\n/**\n * Mounts the self-service registration page.\n *\n * Separate from {@link withLocalLogin} because the two decisions genuinely are separate: an\n * application whose accounts are provisioned by an administrator still needs password sign-in and\n * password reset. Mount it only alongside a server whose `SparkLocalCredentials` is `Full` — with\n * `SignInOnly` the endpoint it posts to is not mapped.\n */\nexport function withRegistration(entry?: SparkAuthRouteEntry): SparkAuthRoutesFeature {\n const register = entryPath(entry, 'register');\n\n return {\n paths: { register: '/' + register },\n children: [\n child(entry, register,\n () => import('@mintplayer/ng-spark/auth/register').then(m => m.SparkRegisterComponent)),\n ],\n };\n}\n\n/**\n * Mounts the sign-in landing page — a button per external provider the *server* reports.\n *\n * Accepts provider declarations and, in any position, one options object for the page's own path;\n * the two shapes are disjoint, so `withExternalLogin(githubProvider(), facebookProvider())` and\n * `withExternalLogin({ signIn: 'landing' }, githubProvider())` both read naturally.\n *\n * Declaring no providers is valid and useful: the page still renders whatever\n * `GET /spark/auth/capabilities` reports, using default buttons.\n */\nexport function withExternalLogin(\n ...providersOrOptions: (SparkExternalProviderPresentation | SparkExternalLoginRouteOptions)[]\n): SparkAuthRoutesFeature {\n const providers = providersOrOptions.filter(isProvider);\n const options = providersOrOptions.find((p): p is SparkExternalLoginRouteOptions => !isProvider(p));\n const signIn = entryPath(options?.signIn, 'sign-in');\n\n return {\n paths: { signIn: '/' + signIn },\n providers,\n children: [\n child(options?.signIn, signIn,\n () => import('@mintplayer/ng-spark/auth/sign-in').then(m => m.SparkSignInComponent)),\n ],\n };\n}\n\nfunction isProvider(\n value: SparkExternalProviderPresentation | SparkExternalLoginRouteOptions,\n): value is SparkExternalProviderPresentation {\n return typeof (value as SparkExternalProviderPresentation).scheme === 'string';\n}\n\n/**\n * Presentation for one provider's button, keyed by the scheme the server reports.\n *\n * The generic form. `githubProvider()` and friends are this with a scheme and an icon filled in —\n * they exist so the common case does not require knowing the scheme string, not because the library\n * has an opinion about which providers exist.\n */\n/**\n * Mounts the passkey management path, which forwards to the generic passkeys page (`/po/passkeys/me`).\n *\n * Independent of every other feature here, and of the server's `SparkLocalCredentials`: a passkey is\n * a passwordless credential, so the applications most likely to want this page are exactly the ones\n * that mount no password pages at all. It pairs with `SparkPasskeys.Enabled` on the server.\n *\n * ⚠️ The page assumes a signed-in user — enrollment adds a credential to an existing account, it\n * cannot create one. Mount it inside the application's authenticated area, or behind\n * `sparkAuthGuard`; the server answers the page with 404 to a visitor who is not signed in.\n */\nexport function withPasskeys(entry?: SparkAuthRouteEntry): SparkAuthRoutesFeature {\n const passkeys = entryPath(entry, 'passkeys');\n\n return {\n paths: { passkeys: '/' + passkeys },\n children: [passkeysChild(entry, passkeys, [])],\n };\n}\n\n/** Options for {@link withAccount}: a path/component per page, and the guard of the signed-in pages. */\nexport type SparkAccountRouteOptions =\n Pick<SparkAuthRouteEntries, 'confirmEmail' | 'account' | 'profile' | 'changePassword' | 'twoFactorSetup' | 'externalLogins' | 'passkeys' | 'personalData'>\n & {\n /**\n * Guards the signed-in pages (everything but confirm-email). Defaults to `[sparkAuthGuard]`,\n * which waits for the session check so a hard reload does not bounce a signed-in user to the\n * sign-in page. Pass `[]` when the pages sit under a guarded parent route already.\n */\n canActivate?: CanActivateFn[];\n /**\n * Pages to leave out, e.g. `['externalLogins']` for an app without external providers or\n * `['changePassword']` under `SparkLocalCredentials.Disabled` (the endpoint is not mapped there).\n */\n exclude?: (keyof Omit<SparkAccountRouteOptions, 'canActivate' | 'exclude'>)[];\n };\n\n/**\n * Mounts the account pages (#460, D16), each also usable as a standalone component:\n *\n * | page | default path | component |\n * |---|---|---|\n * | confirm email (public; the mail link target) | `confirm-email` | `SparkConfirmEmailComponent` |\n * | overview | `account` | `SparkAccountOverviewComponent` |\n * | profile (user name, email change, mail language, app fields) | `account/profile` | `SparkAccountProfileComponent` |\n * | change / set password | `account/password` | `SparkChangePasswordComponent` |\n * | two-factor (authenticator, recovery codes) | `account/two-factor` | `SparkTwoFactorSetupComponent` |\n * | connected logins | `account/logins` | `SparkExternalLoginsComponent` |\n * | passkeys (forwards to the generic page, `/po/passkeys/me`) | `account/passkeys` | — |\n * | personal data + account deletion | `account/personal-data` | `SparkPersonalDataComponent` |\n *\n * `confirm-email` must stay at the server's `Spark:Auth:Links:ConfirmEmailPath` (default\n * `/confirm-email`), which confirmation mails link to. No path has a parameterised first segment, so the\n * group neither shadows `sparkRoutes()` nor is shadowed by it.\n */\nexport function withAccount(options?: SparkAccountRouteOptions): SparkAuthRoutesFeature {\n const guard = options?.canActivate ?? [sparkAuthGuard];\n const excluded = new Set(options?.exclude ?? []);\n const paths: SparkAuthRoutePaths = {};\n const children: Child[] = [];\n\n const add = (key: keyof SparkAccountRouteOptions & keyof SparkAuthRouteEntries, defaultPath: string, loader: Loader, guarded = true) => {\n if (excluded.has(key as never)) return;\n const entry = options?.[key] as SparkAuthRouteEntry | undefined;\n const path = entryPath(entry, defaultPath);\n paths[key] = '/' + path;\n const route = child(entry, path, loader);\n children.push(guarded && guard.length ? { ...route, canActivate: guard } : route);\n };\n\n add('confirmEmail', 'confirm-email',\n () => import('@mintplayer/ng-spark/auth/confirm-email').then(m => m.SparkConfirmEmailComponent), false);\n add('profile', 'account/profile',\n () => import('@mintplayer/ng-spark/auth/account').then(m => m.SparkAccountProfileComponent));\n add('changePassword', 'account/password',\n () => import('@mintplayer/ng-spark/auth/account').then(m => m.SparkChangePasswordComponent));\n add('twoFactorSetup', 'account/two-factor',\n () => import('@mintplayer/ng-spark/auth/account').then(m => m.SparkTwoFactorSetupComponent));\n add('externalLogins', 'account/logins',\n () => import('@mintplayer/ng-spark/auth/account').then(m => m.SparkExternalLoginsComponent));\n if (!excluded.has('passkeys')) {\n const path = entryPath(options?.passkeys, 'account/passkeys');\n paths.passkeys = '/' + path;\n children.push(passkeysChild(options?.passkeys, path, guard));\n }\n add('personalData', 'account/personal-data',\n () => import('@mintplayer/ng-spark/auth/account').then(m => m.SparkPersonalDataComponent));\n add('account', 'account',\n () => import('@mintplayer/ng-spark/auth/account').then(m => m.SparkAccountOverviewComponent));\n\n return { paths, children };\n}\n\nexport function externalProvider(\n scheme: string,\n presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>,\n): SparkExternalProviderPresentation {\n return { scheme, ...presentation };\n}\n\nexport function githubProvider(\n presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>,\n): SparkExternalProviderPresentation {\n return externalProvider('GitHub', { iconClass: 'bi bi-github', ...presentation });\n}\n\nexport function googleProvider(\n presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>,\n): SparkExternalProviderPresentation {\n return externalProvider('Google', { iconClass: 'bi bi-google', ...presentation });\n}\n\nexport function facebookProvider(\n presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>,\n): SparkExternalProviderPresentation {\n return externalProvider('Facebook', { iconClass: 'bi bi-facebook', ...presentation });\n}\n\nexport function microsoftProvider(\n presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>,\n): SparkExternalProviderPresentation {\n return externalProvider('Microsoft', { iconClass: 'bi bi-microsoft', ...presentation });\n}\n\n/** X (formerly Twitter) — the server's `spark.AddTwitter()` preset (OAuth 2.0), scheme `Twitter`. */\nexport function twitterProvider(\n presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>,\n): SparkExternalProviderPresentation {\n return externalProvider('Twitter', { displayName: 'X', iconClass: 'bi bi-twitter-x', ...presentation });\n}\n\n/** LinkedIn — the server's `spark.AddLinkedIn()` preset (OpenID Connect userinfo), scheme `LinkedIn`. */\nexport function linkedInProvider(\n presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>,\n): SparkExternalProviderPresentation {\n return externalProvider('LinkedIn', { iconClass: 'bi bi-linkedin', ...presentation });\n}\n\n/**\n * Any OpenID Connect provider — the client half of the server's OIDC preset\n * (`spark.AddOpenIdConnect(...)`, or a `Spark:Auth:Providers:OpenIdConnect:<scheme>` section). Unlike the named presets the scheme is the\n * application's own choice, so it and the button text are required; `scheme` must equal the server's\n * scheme name exactly.\n */\nexport function oidcProvider(\n scheme: string,\n displayName: string,\n iconClass = 'bi bi-person-badge',\n): SparkExternalProviderPresentation {\n return externalProvider(scheme, { displayName, iconClass });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mintplayer-ng-spark-auth-routes.mjs","names":[],"sources":["../../auth/routes/src/spark-auth-routes.ts"],"sourcesContent":["import {\n SPARK_ACCOUNT_OVERVIEW_LINKS,\n SPARK_AUTH_ROUTE_PATHS,\n SPARK_EXTERNAL_PROVIDERS,\n SparkAccountOverviewLink,\n SparkAuthRouteEntries,\n SparkAuthRouteEntry,\n SparkAuthRoutePaths,\n SparkExternalProviderPresentation,\n} from '@mintplayer/ng-spark/auth/models';\n\nimport { inject } from '@angular/core';\nimport { Router, type CanActivateFn } from '@angular/router';\nimport { sparkAuthGuard } from '@mintplayer/ng-spark/auth/guards';\n\ntype Loader = () => Promise<any>;\n\ninterface Child {\n path: string;\n loadComponent?: Loader;\n canActivate?: CanActivateFn[];\n children?: [];\n}\n\n/**\n * The passkeys page: the generic persistent-object page of the Authorization library's virtual\n * `Passkeys` type, one per signed-in user, so the id is the fixed `me` (generic passkeys page PRD D1).\n */\nexport const SPARK_PASSKEYS_PAGE_URL = '/po/passkeys/me';\n\n/** Forwards to {@link SPARK_PASSKEYS_PAGE_URL}. */\nconst toPasskeysPage: CanActivateFn = () => inject(Router).parseUrl(SPARK_PASSKEYS_PAGE_URL);\n\n/**\n * The passkeys path: a redirect into the generic page, kept for bookmarks and the account overview's\n * link (PRD D8). A guard rather than `redirectTo`, because Angular refuses `canActivate` beside\n * `redirectTo` and the sign-in guard must still run first: the router acts on the first guard in\n * array order that does not pass, so an anonymous visitor is sent to sign in, not to a 404. An\n * application that supplies its own component for the entry keeps it.\n */\nfunction passkeysChild(entry: SparkAuthRouteEntry | undefined, path: string, guard: CanActivateFn[]): Child {\n if (typeof entry === 'object' && entry.component) {\n const component = entry.component;\n return { path, loadComponent: () => Promise.resolve(component), ...(guard.length ? { canActivate: guard } : {}) };\n }\n return { path, canActivate: [...guard, toPasskeysPage], children: [] };\n}\n\n/** The routed path for an entry, independent of how its component is loaded. */\nfunction entryPath(entry: SparkAuthRouteEntry | undefined, defaultPath: string): string {\n if (entry === undefined) return defaultPath;\n return typeof entry === 'string' ? entry : entry.path;\n}\n\n/** An explicitly supplied component wins over the library's lazy import. */\nfunction child(entry: SparkAuthRouteEntry | undefined, path: string, defaultLoader: Loader): Child {\n const component = typeof entry === 'object' && entry.component ? entry.component : undefined;\n return { path, loadComponent: component ? () => Promise.resolve(component) : defaultLoader };\n}\n\n/**\n * One opt-in group of authentication pages, passed to {@link sparkAuthRoutes}. Constructed only by\n * ng-spark's entry points: `withLocalLogin()`, `withRegistration()`, `withExternalLogin()`,\n * `withPasskeys()` and `withAccount()` here, and `withIdentityProvider()` from\n * `@mintplayer/ng-spark/identity-provider`. That keeps the set of mountable pages a decision this\n * library makes rather than a shape an application invents.\n */\nexport interface SparkAuthRoutesFeature {\n readonly children: Child[];\n readonly paths: SparkAuthRoutePaths;\n readonly providers?: SparkExternalProviderPresentation[];\n /** Extra links for the account overview (`SPARK_ACCOUNT_OVERVIEW_LINKS`). */\n readonly accountLinks?: SparkAccountOverviewLink[];\n}\n\n/** Path override for the sign-in landing page. Named to stay clear of the core package's\n * `SparkExternalLoginOptions`, which is about the sign-in *call* rather than the route. */\nexport type SparkExternalLoginRouteOptions = Pick<SparkAuthRouteEntries, 'signIn'>;\n\n/**\n * The routes for Spark's authentication pages.\n *\n * **Nothing is mounted unless a feature asks for it.** Passing no features emits no pages at all —\n * opt-in enforced by construction rather than by a flag, matching `provideHttpClient(withFetch())`\n * and `provideRouter(withComponentInputBinding())`. Before this the pages mounted by default and an\n * application had to opt *out*, so every app shipped a registration form whether or not it wanted\n * one.\n *\n * ```ts\n * sparkAuthRoutes(\n * withLocalLogin(),\n * withRegistration(),\n * withExternalLogin(githubProvider(), facebookProvider()),\n * )\n * ```\n *\n * The `import()` expressions live *inside* each feature. That placement is the point: a bundler\n * decides whether to emit a lazy chunk from whether the `import()` call site is reachable, not from\n * whether the route object referencing it survives — so filtering a children array after the fact\n * would still ship every page. A page nobody opted into has no reachable `import()` at all.\n */\nexport function sparkAuthRoutes(...features: SparkAuthRoutesFeature[]): any[] {\n const children: Child[] = [];\n const paths: SparkAuthRoutePaths = {};\n const externalProviders: SparkExternalProviderPresentation[] = [];\n const accountLinks: SparkAccountOverviewLink[] = [];\n\n for (const feature of features) {\n children.push(...feature.children);\n Object.assign(paths, feature.paths);\n if (feature.providers) externalProviders.push(...feature.providers);\n if (feature.accountLinks) accountLinks.push(...feature.accountLinks);\n }\n\n return [\n {\n path: '',\n providers: [\n { provide: SPARK_AUTH_ROUTE_PATHS, useValue: paths },\n { provide: SPARK_EXTERNAL_PROVIDERS, useValue: externalProviders },\n { provide: SPARK_ACCOUNT_OVERVIEW_LINKS, useValue: accountLinks },\n ],\n children,\n },\n ];\n}\n\n/**\n * Mounts the email/password family: login, two-factor, forgot-password, reset-password.\n *\n * These four are one feature rather than four because they form a star centred on the login page and\n * every template dereferences its siblings unconditionally — removing any proper subset leaves a\n * dangling link. Registration is genuinely separable, and is its own feature.\n *\n * Two-factor belongs here because it is reachable only from the login page's `RequiresTwoFactor`\n * branch and posts to the same `/login` endpoint: it is part of password sign-in, not of\n * authentication in general.\n */\nexport function withLocalLogin(\n entries?: Pick<SparkAuthRouteEntries, 'login' | 'twoFactor' | 'forgotPassword' | 'resetPassword'>,\n): SparkAuthRoutesFeature {\n const login = entryPath(entries?.login, 'login');\n const twoFactor = entryPath(entries?.twoFactor, 'login/two-factor');\n const forgotPassword = entryPath(entries?.forgotPassword, 'forgot-password');\n const resetPassword = entryPath(entries?.resetPassword, 'reset-password');\n\n return {\n paths: {\n login: '/' + login,\n twoFactor: '/' + twoFactor,\n forgotPassword: '/' + forgotPassword,\n resetPassword: '/' + resetPassword,\n },\n children: [\n child(entries?.login, login,\n () => import('@mintplayer/ng-spark/auth/login').then(m => m.SparkLoginComponent)),\n child(entries?.twoFactor, twoFactor,\n () => import('@mintplayer/ng-spark/auth/two-factor').then(m => m.SparkTwoFactorComponent)),\n child(entries?.forgotPassword, forgotPassword,\n () => import('@mintplayer/ng-spark/auth/forgot-password').then(m => m.SparkForgotPasswordComponent)),\n child(entries?.resetPassword, resetPassword,\n () => import('@mintplayer/ng-spark/auth/reset-password').then(m => m.SparkResetPasswordComponent)),\n ],\n };\n}\n\n/**\n * Mounts the self-service registration page.\n *\n * Separate from {@link withLocalLogin} because the two decisions genuinely are separate: an\n * application whose accounts are provisioned by an administrator still needs password sign-in and\n * password reset. Mount it only alongside a server whose `SparkLocalCredentials` is `Full` — with\n * `SignInOnly` the endpoint it posts to is not mapped.\n */\nexport function withRegistration(entry?: SparkAuthRouteEntry): SparkAuthRoutesFeature {\n const register = entryPath(entry, 'register');\n\n return {\n paths: { register: '/' + register },\n children: [\n child(entry, register,\n () => import('@mintplayer/ng-spark/auth/register').then(m => m.SparkRegisterComponent)),\n ],\n };\n}\n\n/**\n * Mounts the sign-in landing page — a button per external provider the *server* reports.\n *\n * Accepts provider declarations and, in any position, one options object for the page's own path;\n * the two shapes are disjoint, so `withExternalLogin(githubProvider(), facebookProvider())` and\n * `withExternalLogin({ signIn: 'landing' }, githubProvider())` both read naturally.\n *\n * Declaring no providers is valid and useful: the page still renders whatever\n * `GET /spark/auth/capabilities` reports, using default buttons.\n */\nexport function withExternalLogin(\n ...providersOrOptions: (SparkExternalProviderPresentation | SparkExternalLoginRouteOptions)[]\n): SparkAuthRoutesFeature {\n const providers = providersOrOptions.filter(isProvider);\n const options = providersOrOptions.find((p): p is SparkExternalLoginRouteOptions => !isProvider(p));\n const signIn = entryPath(options?.signIn, 'sign-in');\n\n return {\n paths: { signIn: '/' + signIn },\n providers,\n children: [\n child(options?.signIn, signIn,\n () => import('@mintplayer/ng-spark/auth/sign-in').then(m => m.SparkSignInComponent)),\n ],\n };\n}\n\nfunction isProvider(\n value: SparkExternalProviderPresentation | SparkExternalLoginRouteOptions,\n): value is SparkExternalProviderPresentation {\n return typeof (value as SparkExternalProviderPresentation).scheme === 'string';\n}\n\n/**\n * Presentation for one provider's button, keyed by the scheme the server reports.\n *\n * The generic form. `githubProvider()` and friends are this with a scheme and an icon filled in —\n * they exist so the common case does not require knowing the scheme string, not because the library\n * has an opinion about which providers exist.\n */\n/**\n * Mounts the passkey management path, which forwards to the generic passkeys page (`/po/passkeys/me`).\n *\n * Independent of every other feature here, and of the server's `SparkLocalCredentials`: a passkey is\n * a passwordless credential, so the applications most likely to want this page are exactly the ones\n * that mount no password pages at all. It pairs with `SparkPasskeys.Enabled` on the server.\n *\n * ⚠️ The page assumes a signed-in user — enrollment adds a credential to an existing account, it\n * cannot create one. Mount it inside the application's authenticated area, or behind\n * `sparkAuthGuard`; the server answers the page with 404 to a visitor who is not signed in.\n */\nexport function withPasskeys(entry?: SparkAuthRouteEntry): SparkAuthRoutesFeature {\n const passkeys = entryPath(entry, 'passkeys');\n\n return {\n paths: { passkeys: '/' + passkeys },\n children: [passkeysChild(entry, passkeys, [])],\n };\n}\n\n/** Options for {@link withAccount}: a path/component per page, and the guard of the signed-in pages. */\nexport type SparkAccountRouteOptions =\n Pick<SparkAuthRouteEntries, 'confirmEmail' | 'account' | 'profile' | 'changePassword' | 'twoFactorSetup' | 'externalLogins' | 'passkeys' | 'personalData'>\n & {\n /**\n * Guards the signed-in pages (everything but confirm-email). Defaults to `[sparkAuthGuard]`,\n * which waits for the session check so a hard reload does not bounce a signed-in user to the\n * sign-in page. Pass `[]` when the pages sit under a guarded parent route already.\n */\n canActivate?: CanActivateFn[];\n /**\n * Pages to leave out, e.g. `['externalLogins']` for an app without external providers or\n * `['changePassword']` under `SparkLocalCredentials.Disabled` (the endpoint is not mapped there).\n */\n exclude?: (keyof Omit<SparkAccountRouteOptions, 'canActivate' | 'exclude'>)[];\n };\n\n/**\n * Mounts the account pages (#460, D16), each also usable as a standalone component:\n *\n * | page | default path | component |\n * |---|---|---|\n * | confirm email (public; the mail link target) | `confirm-email` | `SparkConfirmEmailComponent` |\n * | overview | `account` | `SparkAccountOverviewComponent` |\n * | profile (user name, email change, mail language, app fields) | `account/profile` | `SparkAccountProfileComponent` |\n * | change / set password | `account/password` | `SparkChangePasswordComponent` |\n * | two-factor (authenticator, recovery codes) | `account/two-factor` | `SparkTwoFactorSetupComponent` |\n * | connected logins | `account/logins` | `SparkExternalLoginsComponent` |\n * | passkeys (forwards to the generic page, `/po/passkeys/me`) | `account/passkeys` | — |\n * | personal data + account deletion | `account/personal-data` | `SparkPersonalDataComponent` |\n *\n * `confirm-email` must stay at the server's `Spark:Auth:Links:ConfirmEmailPath` (default\n * `/confirm-email`), which confirmation mails link to. No path has a parameterised first segment, so the\n * group neither shadows `sparkRoutes()` nor is shadowed by it.\n */\nexport function withAccount(options?: SparkAccountRouteOptions): SparkAuthRoutesFeature {\n const guard = options?.canActivate ?? [sparkAuthGuard];\n const excluded = new Set(options?.exclude ?? []);\n const paths: SparkAuthRoutePaths = {};\n const children: Child[] = [];\n\n const add = (key: keyof SparkAccountRouteOptions & keyof SparkAuthRouteEntries, defaultPath: string, loader: Loader, guarded = true) => {\n if (excluded.has(key as never)) return;\n const entry = options?.[key] as SparkAuthRouteEntry | undefined;\n const path = entryPath(entry, defaultPath);\n paths[key] = '/' + path;\n const route = child(entry, path, loader);\n children.push(guarded && guard.length ? { ...route, canActivate: guard } : route);\n };\n\n add('confirmEmail', 'confirm-email',\n () => import('@mintplayer/ng-spark/auth/confirm-email').then(m => m.SparkConfirmEmailComponent), false);\n add('profile', 'account/profile',\n () => import('@mintplayer/ng-spark/auth/account').then(m => m.SparkAccountProfileComponent));\n add('changePassword', 'account/password',\n () => import('@mintplayer/ng-spark/auth/account').then(m => m.SparkChangePasswordComponent));\n add('twoFactorSetup', 'account/two-factor',\n () => import('@mintplayer/ng-spark/auth/account').then(m => m.SparkTwoFactorSetupComponent));\n add('externalLogins', 'account/logins',\n () => import('@mintplayer/ng-spark/auth/account').then(m => m.SparkExternalLoginsComponent));\n if (!excluded.has('passkeys')) {\n const path = entryPath(options?.passkeys, 'account/passkeys');\n paths.passkeys = '/' + path;\n children.push(passkeysChild(options?.passkeys, path, guard));\n }\n add('personalData', 'account/personal-data',\n () => import('@mintplayer/ng-spark/auth/account').then(m => m.SparkPersonalDataComponent));\n add('account', 'account',\n () => import('@mintplayer/ng-spark/auth/account').then(m => m.SparkAccountOverviewComponent));\n\n return { paths, children };\n}\n\n/** Options for {@link withConnectedAgents}. */\nexport type SparkConnectedAgentsRouteOptions = Pick<SparkAuthRouteEntries, 'agents'> & {\n /** Guards the page. Defaults to `[sparkAuthGuard]`; pass `[]` under a guarded parent route. */\n canActivate?: CanActivateFn[];\n};\n\n/**\n * Mounts **Connected applications** (MCP PRD D14) at `account/agents` (`SparkConnectedAgentsComponent`): the AI\n * agents the user connected and their personal access tokens — what each may see, whether it may make changes,\n * when it was last used — with edit, disconnect and \"create token\"; then what other packages contribute. Adds a\n * link to the account overview (`SPARK_ACCOUNT_OVERVIEW_LINKS`).\n *\n * Opt-in, because the page needs the server's `MintPlayer.Spark.Mcp` package: without it\n * `/spark/auth/manage/agents` is not mapped.\n */\nexport function withConnectedAgents(options?: SparkConnectedAgentsRouteOptions): SparkAuthRoutesFeature {\n const guard = options?.canActivate ?? [sparkAuthGuard];\n const path = entryPath(options?.agents, 'account/agents');\n const route = child(options?.agents, path,\n () => import('@mintplayer/ng-spark/auth/account').then(m => m.SparkConnectedAgentsComponent));\n\n return {\n paths: { agents: '/' + path },\n children: [guard.length ? { ...route, canActivate: guard } : route],\n accountLinks: [{\n key: 'agents',\n path: '/' + path,\n label: { en: 'Connected applications', fr: 'Applications connectées', nl: 'Gekoppelde toepassingen' },\n }],\n };\n}\n\nexport function externalProvider(\n scheme: string,\n presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>,\n): SparkExternalProviderPresentation {\n return { scheme, ...presentation };\n}\n\nexport function githubProvider(\n presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>,\n): SparkExternalProviderPresentation {\n return externalProvider('GitHub', { iconClass: 'bi bi-github', ...presentation });\n}\n\nexport function googleProvider(\n presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>,\n): SparkExternalProviderPresentation {\n return externalProvider('Google', { iconClass: 'bi bi-google', ...presentation });\n}\n\nexport function facebookProvider(\n presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>,\n): SparkExternalProviderPresentation {\n return externalProvider('Facebook', { iconClass: 'bi bi-facebook', ...presentation });\n}\n\nexport function microsoftProvider(\n presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>,\n): SparkExternalProviderPresentation {\n return externalProvider('Microsoft', { iconClass: 'bi bi-microsoft', ...presentation });\n}\n\n/** X (formerly Twitter) — the server's `spark.AddTwitter()` preset (OAuth 2.0), scheme `Twitter`. */\nexport function twitterProvider(\n presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>,\n): SparkExternalProviderPresentation {\n return externalProvider('Twitter', { displayName: 'X', iconClass: 'bi bi-twitter-x', ...presentation });\n}\n\n/** LinkedIn — the server's `spark.AddLinkedIn()` preset (OpenID Connect userinfo), scheme `LinkedIn`. */\nexport function linkedInProvider(\n presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>,\n): SparkExternalProviderPresentation {\n return externalProvider('LinkedIn', { iconClass: 'bi bi-linkedin', ...presentation });\n}\n\n/**\n * Any OpenID Connect provider — the client half of the server's OIDC preset\n * (`spark.AddOpenIdConnect(...)`, or a `Spark:Auth:Providers:OpenIdConnect:<scheme>` section). Unlike the named presets the scheme is the\n * application's own choice, so it and the button text are required; `scheme` must equal the server's\n * scheme name exactly.\n */\nexport function oidcProvider(\n scheme: string,\n displayName: string,\n iconClass = 'bi bi-person-badge',\n): SparkExternalProviderPresentation {\n return externalProvider(scheme, { displayName, iconClass });\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SparkAccountProfileField, SparkAccountResult, SparkAuthCapabilities, SparkAuthRoutePaths, SparkAuthenticatorUri, SparkExternalLogins, SparkTwoFactorState } from "@mintplayer/ng-spark/auth/models";
|
|
1
|
+
import { SparkAccountProfileField, SparkAccountResult, SparkAgentExposedType, SparkAgentGrant, SparkAgentGrantType, SparkAgentGrantsOverview, SparkAuthCapabilities, SparkAuthRoutePaths, SparkAuthenticatorUri, SparkContributedApplication, SparkExternalLogins, SparkTwoFactorState, sparkAgentCanWrite } from "@mintplayer/ng-spark/auth/models";
|
|
2
2
|
import { SparkAuthService } from "@mintplayer/ng-spark/auth/core";
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
4
|
import { OnInit } from "@angular/core";
|
|
@@ -252,4 +252,59 @@ export declare class SparkPersonalDataComponent implements OnInit {
|
|
|
252
252
|
deleteAccount(): Promise<void>;
|
|
253
253
|
static ɵfac: i0.ɵɵFactoryDeclaration<SparkPersonalDataComponent, never>;
|
|
254
254
|
static ɵcmp: i0.ɵɵComponentDeclaration<SparkPersonalDataComponent, "spark-personal-data", never, {}, {}, never, never, true, never>;
|
|
255
|
+
}
|
|
256
|
+
/** A choice of what an agent may do: read or read + changes, and every exposed type or a chosen list. */
|
|
257
|
+
interface GrantChoice {
|
|
258
|
+
changes: boolean;
|
|
259
|
+
/** `null`: everything the application makes available to agents (including types exposed later). */
|
|
260
|
+
types: string[] | null;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Connected applications (MCP PRD D14, mounted by `withConnectedAgents()`): the AI agents the user connected
|
|
264
|
+
* and their personal access tokens, with what each may see and whether it may make changes; edit, disconnect,
|
|
265
|
+
* create a token; then what other packages contribute (sign-ins at other websites).
|
|
266
|
+
*
|
|
267
|
+
* The page offers only what an agent could use: the application's limit for that agent and the types the user
|
|
268
|
+
* may see. A change applies to the agent's next call, without signing in again. A new token is shown once.
|
|
269
|
+
*/
|
|
270
|
+
export declare class SparkConnectedAgentsComponent implements OnInit {
|
|
271
|
+
private readonly auth;
|
|
272
|
+
private readonly translation;
|
|
273
|
+
protected readonly colors: typeof Color;
|
|
274
|
+
readonly loading: import("@angular/core").WritableSignal<boolean>;
|
|
275
|
+
readonly busy: import("@angular/core").WritableSignal<boolean>;
|
|
276
|
+
readonly overview: import("@angular/core").WritableSignal<SparkAgentGrantsOverview | null>;
|
|
277
|
+
readonly messages: import("@angular/core").WritableSignal<string[]>;
|
|
278
|
+
/** The key of the grant being edited. */
|
|
279
|
+
readonly editing: import("@angular/core").WritableSignal<string | null>;
|
|
280
|
+
readonly creating: import("@angular/core").WritableSignal<boolean>;
|
|
281
|
+
readonly draft: import("@angular/core").WritableSignal<GrantChoice>;
|
|
282
|
+
readonly tokenName: import("@angular/core").WritableSignal<string>;
|
|
283
|
+
readonly tokenDays: import("@angular/core").WritableSignal<number>;
|
|
284
|
+
/** The token just created: shown until the next change on the page, and never again. */
|
|
285
|
+
readonly createdToken: import("@angular/core").WritableSignal<string | null>;
|
|
286
|
+
readonly draftValid: import("@angular/core").Signal<boolean>;
|
|
287
|
+
readonly tokenValid: import("@angular/core").Signal<boolean>;
|
|
288
|
+
protected readonly canWrite: typeof sparkAgentCanWrite;
|
|
289
|
+
ngOnInit(): Promise<void>;
|
|
290
|
+
load(): Promise<void>;
|
|
291
|
+
edit(grant: SparkAgentGrant): void;
|
|
292
|
+
startToken(): void;
|
|
293
|
+
setChanges(changes: boolean): void;
|
|
294
|
+
setEverything(everything: boolean): void;
|
|
295
|
+
setType(type: SparkAgentExposedType, chosen: boolean): void;
|
|
296
|
+
save(grant: SparkAgentGrant): Promise<void>;
|
|
297
|
+
createToken(): Promise<void>;
|
|
298
|
+
revoke(grant: SparkAgentGrant): Promise<void>;
|
|
299
|
+
revokeApplication(app: SparkContributedApplication): Promise<void>;
|
|
300
|
+
protected typeLabels(types: SparkAgentGrantType[]): string;
|
|
301
|
+
protected date(iso: string | null): string;
|
|
302
|
+
protected value(event: Event): string;
|
|
303
|
+
protected copy(token: string): void;
|
|
304
|
+
private permission;
|
|
305
|
+
/** Each chosen type gets what the grant gets, within what the type itself allows. */
|
|
306
|
+
private types;
|
|
307
|
+
private run;
|
|
308
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SparkConnectedAgentsComponent, never>;
|
|
309
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SparkConnectedAgentsComponent, "spark-connected-agents", never, {}, {}, never, never, true, never>;
|
|
255
310
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AuthUser, SparkAccountInfo, SparkAccountProfile, SparkAccountProfileUpdate, SparkAccountResult, SparkAuthCapabilities, SparkAuthenticatorUri, SparkExternalLoginError, SparkExternalLoginOptions, SparkExternalLoginResult, SparkExternalLoginTwoFactor, SparkExternalLogins, SparkPasskeyResult, SparkTwoFactorRequest, SparkTwoFactorState, SparkUnlinkResult } from "@mintplayer/ng-spark/auth/models";
|
|
1
|
+
import { AuthUser, SparkAccountInfo, SparkAccountProfile, SparkAccountProfileUpdate, SparkAccountResult, SparkAgentGrantUpdate, SparkAgentGrantsOverview, SparkAgentTokenCreated, SparkAgentTokenRequest, SparkAuthCapabilities, SparkAuthenticatorUri, SparkExternalLoginError, SparkExternalLoginOptions, SparkExternalLoginResult, SparkExternalLoginTwoFactor, SparkExternalLogins, SparkPasskeyResult, SparkTwoFactorRequest, SparkTwoFactorState, SparkUnlinkResult } from "@mintplayer/ng-spark/auth/models";
|
|
2
2
|
import * as i0 from "@angular/core";
|
|
3
3
|
export declare class SparkAuthService {
|
|
4
4
|
private readonly http;
|
|
@@ -171,6 +171,16 @@ export declare class SparkAuthService {
|
|
|
171
171
|
* success the session is gone.
|
|
172
172
|
*/
|
|
173
173
|
deleteAccount(password?: string | null): Promise<SparkAccountResult>;
|
|
174
|
+
/** `GET /manage/agents` — the user's grants, what may be granted, and contributed entries. */
|
|
175
|
+
agentGrants(): Promise<SparkAccountResult<SparkAgentGrantsOverview>>;
|
|
176
|
+
/** `POST /manage/agents/tokens` — the answer carries the token, once; it cannot be read again. */
|
|
177
|
+
createAgentToken(request: SparkAgentTokenRequest): Promise<SparkAccountResult<SparkAgentTokenCreated>>;
|
|
178
|
+
/** `POST /manage/agents/update` — the agent's next call uses the new choice; no new sign-in. */
|
|
179
|
+
updateAgentGrant(update: SparkAgentGrantUpdate): Promise<SparkAccountResult>;
|
|
180
|
+
/** `POST /manage/agents/revoke` — disconnects the agent (or revokes the token) at once. */
|
|
181
|
+
revokeAgentGrant(key: string): Promise<SparkAccountResult>;
|
|
182
|
+
/** `POST /manage/agents/applications/revoke` — revokes an entry another package contributed. */
|
|
183
|
+
revokeConnectedApplication(source: string, id: string): Promise<SparkAccountResult>;
|
|
174
184
|
private accountCall;
|
|
175
185
|
/**
|
|
176
186
|
* Signs in with a passkey.
|
|
@@ -252,6 +252,11 @@ export interface SparkAuthRouteEntries {
|
|
|
252
252
|
* `withIdentityProvider(withConnectedApplications())` from `@mintplayer/ng-spark/identity-provider`.
|
|
253
253
|
*/
|
|
254
254
|
connectedApplications?: SparkAuthRouteEntry;
|
|
255
|
+
/**
|
|
256
|
+
* The AI agents and personal access tokens the user connected (MCP), mounted by `withConnectedAgents()`.
|
|
257
|
+
* Needs the server's `MintPlayer.Spark.Mcp` package.
|
|
258
|
+
*/
|
|
259
|
+
agents?: SparkAuthRouteEntry;
|
|
255
260
|
/** The developer portal's landing page (`withIdentityProvider(withDeveloperRoutes())`). */
|
|
256
261
|
developers?: SparkAuthRouteEntry;
|
|
257
262
|
/** The identity provider's management page (`withIdentityProvider(withManagementRoutes())`). */
|
|
@@ -486,4 +491,94 @@ export interface SparkAccountProfileField {
|
|
|
486
491
|
/** Multi-provider: the application's profile fields. Use {@link provideSparkAccountProfileFields}. */
|
|
487
492
|
export declare const SPARK_ACCOUNT_PROFILE_FIELDS: InjectionToken<SparkAccountProfileField[]>;
|
|
488
493
|
/** Registers profile fields; every call adds. */
|
|
489
|
-
export declare function provideSparkAccountProfileFields(...fields: SparkAccountProfileField[]): Provider[];
|
|
494
|
+
export declare function provideSparkAccountProfileFields(...fields: SparkAccountProfileField[]): Provider[];
|
|
495
|
+
/**
|
|
496
|
+
* What an AI agent may do, as the server writes `EAgentPermission`: `'Read'`, `'Read, Write'`, or `'None'`
|
|
497
|
+
* (MCP PRD D6). "Write" is shown to users as "changes".
|
|
498
|
+
*/
|
|
499
|
+
export type SparkAgentPermission = 'None' | 'Read' | 'Write' | 'Read, Write';
|
|
500
|
+
/** Whether `permission` includes changes (`Write`). */
|
|
501
|
+
export declare function sparkAgentCanWrite(permission: SparkAgentPermission | null | undefined): boolean;
|
|
502
|
+
/** One chosen type of a grant. */
|
|
503
|
+
export interface SparkAgentGrantType {
|
|
504
|
+
name: string;
|
|
505
|
+
permissions: SparkAgentPermission;
|
|
506
|
+
}
|
|
507
|
+
/** An entity type the application makes available to agents and the user may see, with its own most. */
|
|
508
|
+
export interface SparkAgentExposedType {
|
|
509
|
+
name: string;
|
|
510
|
+
label: string;
|
|
511
|
+
permissions: SparkAgentPermission;
|
|
512
|
+
/** Labels of the type's queries, shown under it. */
|
|
513
|
+
queries: string[];
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* One agent grant (`AgentGrant`): what the user allowed one agent. `types: null` means everything the
|
|
517
|
+
* application makes available to agents, including types exposed later.
|
|
518
|
+
*/
|
|
519
|
+
export interface SparkAgentGrant {
|
|
520
|
+
/** Identifies the grant in requests (`pat/…`, `ext/…`, `app/…`); the user's own grants only. */
|
|
521
|
+
key: string;
|
|
522
|
+
/** `PersonalAccessToken`, `MetadataDocument`, `DynamicRegistration`, `PreRegistered`, `ExternalAuthorizationServer`. */
|
|
523
|
+
kind: string;
|
|
524
|
+
/** A token's name, or the name an OAuth client gives itself (unverified unless `verifiedHost` is set). */
|
|
525
|
+
name: string | null;
|
|
526
|
+
clientId: string | null;
|
|
527
|
+
/** Set only when the client's identity was verified (its metadata document was fetched from this host). */
|
|
528
|
+
verifiedHost: string | null;
|
|
529
|
+
/** For `ExternalAuthorizationServer`: the issuer of the server the agent signed in at. */
|
|
530
|
+
issuer?: string | null;
|
|
531
|
+
permissions: SparkAgentPermission;
|
|
532
|
+
types: SparkAgentGrantType[] | null;
|
|
533
|
+
/** The most this grant may be given (the application's limit for this agent). */
|
|
534
|
+
maxPermissions: SparkAgentPermission;
|
|
535
|
+
createdAt: string;
|
|
536
|
+
expiresAt: string | null;
|
|
537
|
+
lastUsedAt: string | null;
|
|
538
|
+
/**
|
|
539
|
+
* `revoked`: the token stopped working because the password or sign-in methods changed. `disconnected`: an external
|
|
540
|
+
* authorization server's agent the user disconnected, or one a password or sign-in-method change disconnected; an
|
|
541
|
+
* edit allows it again.
|
|
542
|
+
*/
|
|
543
|
+
status: 'active' | 'expired' | 'revoked' | 'disconnected';
|
|
544
|
+
}
|
|
545
|
+
/** An entry another package contributed (e.g. sign-ins at other websites, from the identity provider). */
|
|
546
|
+
export interface SparkContributedApplication {
|
|
547
|
+
source: string;
|
|
548
|
+
id: string;
|
|
549
|
+
name: string;
|
|
550
|
+
description: string | null;
|
|
551
|
+
createdAt: string | null;
|
|
552
|
+
lastUsedAt: string | null;
|
|
553
|
+
}
|
|
554
|
+
/** `GET /spark/auth/manage/agents`. */
|
|
555
|
+
export interface SparkAgentGrantsOverview {
|
|
556
|
+
/** Whether personal access tokens can be created here. */
|
|
557
|
+
personalAccessTokens: boolean;
|
|
558
|
+
defaultTokenLifetimeDays: number;
|
|
559
|
+
maxTokenLifetimeDays: number;
|
|
560
|
+
/** The most a new token may be granted. */
|
|
561
|
+
tokenPermissions: SparkAgentPermission;
|
|
562
|
+
types: SparkAgentExposedType[];
|
|
563
|
+
grants: SparkAgentGrant[];
|
|
564
|
+
applications: SparkContributedApplication[];
|
|
565
|
+
}
|
|
566
|
+
/** The body of `POST /spark/auth/manage/agents/tokens`. Omit `types` for everything exposed. */
|
|
567
|
+
export interface SparkAgentTokenRequest {
|
|
568
|
+
name: string;
|
|
569
|
+
expiresInDays?: number;
|
|
570
|
+
permissions: SparkAgentPermission;
|
|
571
|
+
types?: SparkAgentGrantType[] | null;
|
|
572
|
+
}
|
|
573
|
+
/** The answer of `POST /spark/auth/manage/agents/tokens`: the only time the token is ever shown. */
|
|
574
|
+
export interface SparkAgentTokenCreated {
|
|
575
|
+
token: string;
|
|
576
|
+
key: string;
|
|
577
|
+
expiresAt: string;
|
|
578
|
+
}
|
|
579
|
+
/** The body of `POST /spark/auth/manage/agents/update`. `types: null` for everything exposed. */
|
|
580
|
+
export interface SparkAgentGrantUpdate {
|
|
581
|
+
key: string;
|
|
582
|
+
permissions: SparkAgentPermission;
|
|
583
|
+
types: SparkAgentGrantType[] | null;
|
|
584
|
+
}
|
|
@@ -5,7 +5,18 @@ export declare class SparkRegisterComponent {
|
|
|
5
5
|
private readonly authService;
|
|
6
6
|
private readonly router;
|
|
7
7
|
private readonly translation;
|
|
8
|
+
private readonly route;
|
|
8
9
|
readonly routePaths: Partial<Record<keyof import("@mintplayer/ng-spark/auth/models").SparkAuthRouteEntries, string>>;
|
|
10
|
+
/**
|
|
11
|
+
* Carries a local `returnUrl` on to the sign-in step, e.g. the identity provider's pending
|
|
12
|
+
* authorization from its sign-in page's "Create an account" link. Anything else is dropped (R2-H9).
|
|
13
|
+
*/
|
|
14
|
+
private readonly returnUrl;
|
|
15
|
+
readonly returnUrlParams: {
|
|
16
|
+
returnUrl: string | null;
|
|
17
|
+
} | {
|
|
18
|
+
returnUrl?: undefined;
|
|
19
|
+
};
|
|
9
20
|
colors: typeof Color;
|
|
10
21
|
readonly loading: import("@angular/core").WritableSignal<boolean>;
|
|
11
22
|
readonly errorMessage: import("@angular/core").WritableSignal<string>;
|
|
@@ -15,6 +26,8 @@ export declare class SparkRegisterComponent {
|
|
|
15
26
|
password: import("@angular/forms").FormControl<string | null>;
|
|
16
27
|
confirmPassword: import("@angular/forms").FormControl<string | null>;
|
|
17
28
|
}>;
|
|
29
|
+
/** A full page load, for a server route the router can't reach. A method so tests can replace it. */
|
|
30
|
+
protected leaveTo(url: string): void;
|
|
18
31
|
onSubmit(): Promise<void>;
|
|
19
32
|
static ɵfac: i0.ɵɵFactoryDeclaration<SparkRegisterComponent, never>;
|
|
20
33
|
static ɵcmp: i0.ɵɵComponentDeclaration<SparkRegisterComponent, "spark-register", never, {}, {}, never, never, true, never>;
|
|
@@ -136,6 +136,21 @@ export type SparkAccountRouteOptions = Pick<SparkAuthRouteEntries, 'confirmEmail
|
|
|
136
136
|
* group neither shadows `sparkRoutes()` nor is shadowed by it.
|
|
137
137
|
*/
|
|
138
138
|
export declare function withAccount(options?: SparkAccountRouteOptions): SparkAuthRoutesFeature;
|
|
139
|
+
/** Options for {@link withConnectedAgents}. */
|
|
140
|
+
export type SparkConnectedAgentsRouteOptions = Pick<SparkAuthRouteEntries, 'agents'> & {
|
|
141
|
+
/** Guards the page. Defaults to `[sparkAuthGuard]`; pass `[]` under a guarded parent route. */
|
|
142
|
+
canActivate?: CanActivateFn[];
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Mounts **Connected applications** (MCP PRD D14) at `account/agents` (`SparkConnectedAgentsComponent`): the AI
|
|
146
|
+
* agents the user connected and their personal access tokens — what each may see, whether it may make changes,
|
|
147
|
+
* when it was last used — with edit, disconnect and "create token"; then what other packages contribute. Adds a
|
|
148
|
+
* link to the account overview (`SPARK_ACCOUNT_OVERVIEW_LINKS`).
|
|
149
|
+
*
|
|
150
|
+
* Opt-in, because the page needs the server's `MintPlayer.Spark.Mcp` package: without it
|
|
151
|
+
* `/spark/auth/manage/agents` is not mapped.
|
|
152
|
+
*/
|
|
153
|
+
export declare function withConnectedAgents(options?: SparkConnectedAgentsRouteOptions): SparkAuthRoutesFeature;
|
|
139
154
|
export declare function externalProvider(scheme: string, presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>): SparkExternalProviderPresentation;
|
|
140
155
|
export declare function githubProvider(presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>): SparkExternalProviderPresentation;
|
|
141
156
|
export declare function googleProvider(presentation?: Omit<SparkExternalProviderPresentation, 'scheme'>): SparkExternalProviderPresentation;
|