@sneat/auth-ui 0.5.0 → 0.5.2

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.
@@ -5,7 +5,7 @@ import { Capacitor } from '@capacitor/core';
5
5
  import { NavController, IonBackButton, IonButtons, IonCard, IonCardContent, IonCol, IonContent, IonGrid, IonHeader, IonIcon, IonItem, IonItemDivider, IonLabel, IonList, IonRow, IonSpinner, IonText, IonTitle, IonToolbar, } from '@ionic/angular/standalone';
6
6
  import { AuthStatuses, LoginEventsHandler, SneatAuthStateService, } from '@sneat/auth-core';
7
7
  import { SneatUserService } from '@sneat/auth-core';
8
- import { AnalyticsService, APP_INFO, } from '@sneat/core';
8
+ import { AnalyticsService, APP_INFO, currentSpacePath, } from '@sneat/core';
9
9
  import { RandomIdService } from '@sneat/random';
10
10
  import { ClassName, SneatBaseComponent } from '@sneat/ui';
11
11
  import { Subject, takeUntil } from 'rxjs';
@@ -43,7 +43,8 @@ export class LoginPageComponent extends SneatBaseComponent {
43
43
  else {
44
44
  return;
45
45
  }
46
- const redirectTo = this.redirectTo || '/'; // TODO: default one should be app specific.
46
+ // Fall back to the persisted current space so it is restored after login.
47
+ const redirectTo = this.redirectTo || currentSpacePath() || '/';
47
48
  this.navController
48
49
  .navigateRoot(redirectTo)
49
50
  .catch(this.errorLogger.logErrorHandler('Failed to navigate back to ' + redirectTo));
@@ -1 +1 @@
1
- {"version":3,"file":"login-page.component.js","sourceRoot":"","sources":["../../../../../../../../libs/auth/ui/src/lib/pages/login-page/login-page.component.ts","../../../../../../../../libs/auth/ui/src/lib/pages/login-page/login-page.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, signal, inject } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { ActivatedRoute } from '@angular/router';\nimport { Capacitor } from '@capacitor/core';\nimport {\n NavController,\n IonBackButton,\n IonButtons,\n IonCard,\n IonCardContent,\n IonCol,\n IonContent,\n IonGrid,\n IonHeader,\n IonIcon,\n IonItem,\n IonItemDivider,\n IonLabel,\n IonList,\n IonRow,\n IonSpinner,\n IonText,\n IonTitle,\n IonToolbar,\n} from '@ionic/angular/standalone';\nimport {\n AuthProviderID,\n AuthStatuses,\n ILoginEventsHandler,\n ISneatAuthState,\n LoginEventsHandler,\n SneatAuthStateService,\n} from '@sneat/auth-core';\nimport { SneatUserService } from '@sneat/auth-core';\nimport {\n AnalyticsService,\n APP_INFO,\n IAnalyticsService,\n IAppInfo,\n} from '@sneat/core';\nimport { RandomIdService } from '@sneat/random';\nimport { ClassName, SneatBaseComponent } from '@sneat/ui';\nimport { Subject, takeUntil } from 'rxjs';\nimport {\n EmailFormSigningWith,\n EmailLoginFormComponent,\n} from './email-login-form/email-login-form.component';\nimport { UserCredential } from 'firebase/auth';\nimport { LoginWithTelegramComponent } from './login-with-telegram.component';\n\ntype Action = 'join' | 'refuse'; // TODO: inject provider for action descriptions/messages.\n\n@Component({\n selector: 'sneat-login',\n templateUrl: './login-page.component.html',\n imports: [\n FormsModule,\n LoginWithTelegramComponent,\n EmailLoginFormComponent,\n IonHeader,\n IonToolbar,\n IonButtons,\n IonBackButton,\n IonTitle,\n IonContent,\n IonCardContent,\n IonText,\n IonCard,\n IonItemDivider,\n IonLabel,\n IonRow,\n IonCol,\n IonItem,\n IonSpinner,\n IonIcon,\n IonList,\n IonGrid,\n ],\n providers: [\n {\n provide: ClassName,\n useValue: 'LoginPageComponent',\n },\n RandomIdService,\n ],\n})\nexport class LoginPageComponent extends SneatBaseComponent {\n private readonly analyticsService =\n inject<IAnalyticsService>(AnalyticsService);\n private readonly route = inject(ActivatedRoute);\n private readonly navController = inject(NavController);\n private readonly userService = inject(SneatUserService);\n private readonly authStateService = inject(SneatAuthStateService);\n private appInfo = inject<IAppInfo>(APP_INFO);\n private readonly loginEventsHandler = inject<ILoginEventsHandler>(\n LoginEventsHandler,\n { optional: true },\n );\n\n protected readonly signingWith = signal<AuthProviderID | undefined>(\n undefined,\n );\n private readonly redirectTo?: string;\n protected readonly to?: string;\n protected readonly action?: Action; // TODO: document possible values?\n\n protected readonly isNativePlatform = Capacitor.isNativePlatform();\n\n protected readonly appTitle: string;\n\n constructor() {\n super();\n const appInfo = this.appInfo;\n this.appTitle = appInfo.appTitle || 'Sneat.app';\n if (location.hash.startsWith('#/')) {\n this.redirectTo = location.hash.substring(1);\n }\n this.to = this.route.snapshot.queryParams['to']; // should we subscribe? I believe no.\n const action = location.hash.match(/[#&]action=(\\w+)/);\n this.action = action?.[1] as Action;\n\n const userRecordLoaded = new Subject<void>();\n this.userService.userState\n .pipe(takeUntil(userRecordLoaded), this.takeUntilDestroyed())\n .subscribe({\n next: (userState) => {\n if (userState.record) {\n userRecordLoaded.next();\n } else {\n return;\n }\n const redirectTo = this.redirectTo || '/'; // TODO: default one should be app specific.\n this.navController\n .navigateRoot(redirectTo)\n .catch(\n this.errorLogger.logErrorHandler(\n 'Failed to navigate back to ' + redirectTo,\n ),\n );\n },\n error: this.errorHandler('Failed to get user state after login'),\n });\n }\n\n protected onEmailFormStatusChanged(signingWith?: EmailFormSigningWith): void {\n this.signingWith.set(signingWith as AuthProviderID);\n }\n\n protected async loginWith(provider: AuthProviderID) {\n this.signingWith.set(provider);\n try {\n await this.authStateService.signInWith(provider);\n // We do not reset this.signingWith in case of succesful sign in as we should redirect from login page\n // and not to allow user to do a double sign-in.\n } catch (e) {\n const errMsg = (e as { errorMessage?: string }).errorMessage;\n if (\n errMsg !== 'The user canceled the sign-in flow.' &&\n !errMsg?.includes(\n 'com.apple.AuthenticationServices.AuthorizationError error 1001.',\n )\n ) {\n this.errorLogger.logError(e, `Failed to sign-in with ${provider}`);\n }\n this.signingWith.set(undefined);\n }\n }\n\n protected onLoggedIn(userCredential: UserCredential): void {\n this.signingWith.set(undefined);\n if (!userCredential.user) {\n return;\n }\n if (userCredential.user.email) {\n const prevEmail = localStorage.getItem('emailForSignIn') || '';\n if (!prevEmail) {\n localStorage.setItem('emailForSignIn', userCredential.user.email);\n }\n }\n const authState: ISneatAuthState = {\n status: AuthStatuses.authenticated,\n user: userCredential.user,\n };\n this.userService.onUserSignedIn(authState);\n }\n\n private errorHandler(\n m: string,\n eventName?: string,\n eventParams?: Record<string, string>,\n ): (err: unknown) => void {\n return (err) => this.handleError(err, m, eventName, eventParams);\n }\n\n private handleError(\n err: unknown,\n m: string,\n eventName?: string,\n eventParams?: Record<string, string>,\n ): void {\n if (eventName) {\n this.analyticsService.logEvent(eventName, eventParams);\n }\n this.errorLogger.logError(err, m, {\n report: !(err as { code: unknown }).code,\n });\n this.signingWith.set(undefined);\n }\n}\n","<ion-header>\n <ion-toolbar color=\"light\">\n <ion-buttons slot=\"start\">\n <ion-back-button />\n </ion-buttons>\n <ion-title>Login &#64; {{ appTitle }}</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content id=\"main-content\">\n @if (to) {\n <ion-card color=\"tertiary\">\n <ion-card-content>\n <p>Please sign in to join a team</p>\n </ion-card-content>\n </ion-card>\n }\n\n <p style=\"text-align: center; font-size: smaller\">\n <ion-text color=\"medium\">\n This app is free to use &\n <a target=\"_blank\" href=\"https://github.com/sneat-co\">open source</a>.\n </ion-text>\n </p>\n\n <sneat-email-login-form\n (signingWithChange)=\"onEmailFormStatusChanged()\"\n (loggedIn)=\"onLoggedIn($event)\"\n />\n\n <ion-card>\n <ion-item-divider color=\"light\">\n <ion-label\n color=\"medium\"\n style=\"text-align: center; width: 100%; font-weight: bold\"\n >\n Quick login\n </ion-label>\n </ion-item-divider>\n <ion-grid class=\"ion-grid-layout\">\n @if (!isNativePlatform) {\n <ion-row>\n <ion-col>\n <div class=\"ion-padding\" style=\"text-align: center\">\n <sneat-login-with-telegram />\n </div>\n </ion-col>\n </ion-row>\n }\n <ion-row>\n <ion-col size=\"12\" size-md=\"6\">\n <ion-list lines=\"none\">\n <ion-item\n (click)=\"loginWith('google.com')\"\n tappable\n [disabled]=\"!!signingWith()\"\n >\n @if (signingWith() === \"google.com\") {\n <ion-spinner slot=\"start\" name=\"lines-small\" />\n } @else {\n <ion-icon color=\"danger\" name=\"logo-google\" slot=\"start\" />\n }\n <ion-label color=\"danger\"> Login with Google</ion-label>\n </ion-item>\n </ion-list>\n </ion-col>\n <ion-col size=\"12\" size-md=\"6\">\n <ion-list lines=\"none\">\n <ion-item\n (click)=\"loginWith('apple.com')\"\n tappable\n [disabled]=\"!!signingWith()\"\n >\n @if (signingWith() === \"apple.com\") {\n <ion-spinner slot=\"start\" name=\"lines-small\" />\n } @else {\n <ion-icon color=\"dark\" name=\"logo-apple\" slot=\"start\" />\n }\n\n <ion-label color=\"dark\"> Login with Apple</ion-label>\n </ion-item>\n </ion-list>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col size=\"12\" size-md=\"6\">\n <ion-list lines=\"none\">\n <ion-item\n (click)=\"loginWith('microsoft.com')\"\n tappable\n [disabled]=\"!!signingWith()\"\n >\n @if (signingWith() === \"microsoft.com\") {\n <ion-spinner\n slot=\"start\"\n color=\"secondary\"\n name=\"lines-small\"\n />\n } @else {\n <ion-icon slot=\"start\" color=\"secondary\" name=\"logo-windows\" />\n }\n <ion-label color=\"secondary\">Login with Microsoft</ion-label>\n </ion-item>\n </ion-list>\n </ion-col>\n <ion-col size=\"12\" size-md=\"6\">\n <ion-list lines=\"none\">\n <ion-item\n (click)=\"loginWith('facebook.com')\"\n tappable\n [disabled]=\"!!signingWith()\"\n >\n @if (signingWith() === \"facebook.com\") {\n <ion-spinner slot=\"start\" color=\"primary\" name=\"lines-small\" />\n } @else {\n <ion-icon slot=\"start\" color=\"primary\" name=\"logo-facebook\" />\n }\n <ion-label color=\"primary\">Login with Facebook</ion-label>\n </ion-item>\n </ion-list>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col size=\"12\" size-md=\"6\">\n <ion-list lines=\"none\">\n <ion-item\n (click)=\"loginWith('github.com')\"\n tappable\n [disabled]=\"!!signingWith()\"\n >\n @if (signingWith() === \"github.com\") {\n <ion-spinner slot=\"start\" color=\"tertiary\" name=\"lines-small\" />\n } @else {\n <ion-icon slot=\"start\" color=\"tertiary\" name=\"logo-github\" />\n }\n <ion-label color=\"tertiary\">Login with GitHub</ion-label>\n </ion-item>\n </ion-list>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card>\n\n <p style=\"text-align: center; font-size: smaller\">\n <ion-text color=\"medium\">\n If any issues get\n <a href=\"mailto:help@sneat.app?subject=Problem+with+login+at+Sneat.app\"\n >help&#64;sneat.app</a\n >\n </ion-text>\n </p>\n</ion-content>\n"]}
1
+ {"version":3,"file":"login-page.component.js","sourceRoot":"","sources":["../../../../../../../../libs/auth/ui/src/lib/pages/login-page/login-page.component.ts","../../../../../../../../libs/auth/ui/src/lib/pages/login-page/login-page.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, signal, inject } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { ActivatedRoute } from '@angular/router';\nimport { Capacitor } from '@capacitor/core';\nimport {\n NavController,\n IonBackButton,\n IonButtons,\n IonCard,\n IonCardContent,\n IonCol,\n IonContent,\n IonGrid,\n IonHeader,\n IonIcon,\n IonItem,\n IonItemDivider,\n IonLabel,\n IonList,\n IonRow,\n IonSpinner,\n IonText,\n IonTitle,\n IonToolbar,\n} from '@ionic/angular/standalone';\nimport {\n AuthProviderID,\n AuthStatuses,\n ILoginEventsHandler,\n ISneatAuthState,\n LoginEventsHandler,\n SneatAuthStateService,\n} from '@sneat/auth-core';\nimport { SneatUserService } from '@sneat/auth-core';\nimport {\n AnalyticsService,\n APP_INFO,\n currentSpacePath,\n IAnalyticsService,\n IAppInfo,\n} from '@sneat/core';\nimport { RandomIdService } from '@sneat/random';\nimport { ClassName, SneatBaseComponent } from '@sneat/ui';\nimport { Subject, takeUntil } from 'rxjs';\nimport {\n EmailFormSigningWith,\n EmailLoginFormComponent,\n} from './email-login-form/email-login-form.component';\nimport { UserCredential } from 'firebase/auth';\nimport { LoginWithTelegramComponent } from './login-with-telegram.component';\n\ntype Action = 'join' | 'refuse'; // TODO: inject provider for action descriptions/messages.\n\n@Component({\n selector: 'sneat-login',\n templateUrl: './login-page.component.html',\n imports: [\n FormsModule,\n LoginWithTelegramComponent,\n EmailLoginFormComponent,\n IonHeader,\n IonToolbar,\n IonButtons,\n IonBackButton,\n IonTitle,\n IonContent,\n IonCardContent,\n IonText,\n IonCard,\n IonItemDivider,\n IonLabel,\n IonRow,\n IonCol,\n IonItem,\n IonSpinner,\n IonIcon,\n IonList,\n IonGrid,\n ],\n providers: [\n {\n provide: ClassName,\n useValue: 'LoginPageComponent',\n },\n RandomIdService,\n ],\n})\nexport class LoginPageComponent extends SneatBaseComponent {\n private readonly analyticsService =\n inject<IAnalyticsService>(AnalyticsService);\n private readonly route = inject(ActivatedRoute);\n private readonly navController = inject(NavController);\n private readonly userService = inject(SneatUserService);\n private readonly authStateService = inject(SneatAuthStateService);\n private appInfo = inject<IAppInfo>(APP_INFO);\n private readonly loginEventsHandler = inject<ILoginEventsHandler>(\n LoginEventsHandler,\n { optional: true },\n );\n\n protected readonly signingWith = signal<AuthProviderID | undefined>(\n undefined,\n );\n private readonly redirectTo?: string;\n protected readonly to?: string;\n protected readonly action?: Action; // TODO: document possible values?\n\n protected readonly isNativePlatform = Capacitor.isNativePlatform();\n\n protected readonly appTitle: string;\n\n constructor() {\n super();\n const appInfo = this.appInfo;\n this.appTitle = appInfo.appTitle || 'Sneat.app';\n if (location.hash.startsWith('#/')) {\n this.redirectTo = location.hash.substring(1);\n }\n this.to = this.route.snapshot.queryParams['to']; // should we subscribe? I believe no.\n const action = location.hash.match(/[#&]action=(\\w+)/);\n this.action = action?.[1] as Action;\n\n const userRecordLoaded = new Subject<void>();\n this.userService.userState\n .pipe(takeUntil(userRecordLoaded), this.takeUntilDestroyed())\n .subscribe({\n next: (userState) => {\n if (userState.record) {\n userRecordLoaded.next();\n } else {\n return;\n }\n // Fall back to the persisted current space so it is restored after login.\n const redirectTo = this.redirectTo || currentSpacePath() || '/';\n this.navController\n .navigateRoot(redirectTo)\n .catch(\n this.errorLogger.logErrorHandler(\n 'Failed to navigate back to ' + redirectTo,\n ),\n );\n },\n error: this.errorHandler('Failed to get user state after login'),\n });\n }\n\n protected onEmailFormStatusChanged(signingWith?: EmailFormSigningWith): void {\n this.signingWith.set(signingWith as AuthProviderID);\n }\n\n protected async loginWith(provider: AuthProviderID) {\n this.signingWith.set(provider);\n try {\n await this.authStateService.signInWith(provider);\n // We do not reset this.signingWith in case of succesful sign in as we should redirect from login page\n // and not to allow user to do a double sign-in.\n } catch (e) {\n const errMsg = (e as { errorMessage?: string }).errorMessage;\n if (\n errMsg !== 'The user canceled the sign-in flow.' &&\n !errMsg?.includes(\n 'com.apple.AuthenticationServices.AuthorizationError error 1001.',\n )\n ) {\n this.errorLogger.logError(e, `Failed to sign-in with ${provider}`);\n }\n this.signingWith.set(undefined);\n }\n }\n\n protected onLoggedIn(userCredential: UserCredential): void {\n this.signingWith.set(undefined);\n if (!userCredential.user) {\n return;\n }\n if (userCredential.user.email) {\n const prevEmail = localStorage.getItem('emailForSignIn') || '';\n if (!prevEmail) {\n localStorage.setItem('emailForSignIn', userCredential.user.email);\n }\n }\n const authState: ISneatAuthState = {\n status: AuthStatuses.authenticated,\n user: userCredential.user,\n };\n this.userService.onUserSignedIn(authState);\n }\n\n private errorHandler(\n m: string,\n eventName?: string,\n eventParams?: Record<string, string>,\n ): (err: unknown) => void {\n return (err) => this.handleError(err, m, eventName, eventParams);\n }\n\n private handleError(\n err: unknown,\n m: string,\n eventName?: string,\n eventParams?: Record<string, string>,\n ): void {\n if (eventName) {\n this.analyticsService.logEvent(eventName, eventParams);\n }\n this.errorLogger.logError(err, m, {\n report: !(err as { code: unknown }).code,\n });\n this.signingWith.set(undefined);\n }\n}\n","<ion-header>\n <ion-toolbar color=\"light\">\n <ion-buttons slot=\"start\">\n <ion-back-button />\n </ion-buttons>\n <ion-title>Login &#64; {{ appTitle }}</ion-title>\n </ion-toolbar>\n</ion-header>\n\n<ion-content id=\"main-content\">\n @if (to) {\n <ion-card color=\"tertiary\">\n <ion-card-content>\n <p>Please sign in to join a team</p>\n </ion-card-content>\n </ion-card>\n }\n\n <p style=\"text-align: center; font-size: smaller\">\n <ion-text color=\"medium\">\n This app is free to use &\n <a target=\"_blank\" href=\"https://github.com/sneat-co\">open source</a>.\n </ion-text>\n </p>\n\n <sneat-email-login-form\n (signingWithChange)=\"onEmailFormStatusChanged()\"\n (loggedIn)=\"onLoggedIn($event)\"\n />\n\n <ion-card>\n <ion-item-divider color=\"light\">\n <ion-label\n color=\"medium\"\n style=\"text-align: center; width: 100%; font-weight: bold\"\n >\n Quick login\n </ion-label>\n </ion-item-divider>\n <ion-grid class=\"ion-grid-layout\">\n @if (!isNativePlatform) {\n <ion-row>\n <ion-col>\n <div class=\"ion-padding\" style=\"text-align: center\">\n <sneat-login-with-telegram />\n </div>\n </ion-col>\n </ion-row>\n }\n <ion-row>\n <ion-col size=\"12\" size-md=\"6\">\n <ion-list lines=\"none\">\n <ion-item\n (click)=\"loginWith('google.com')\"\n tappable\n [disabled]=\"!!signingWith()\"\n >\n @if (signingWith() === \"google.com\") {\n <ion-spinner slot=\"start\" name=\"lines-small\" />\n } @else {\n <ion-icon color=\"danger\" name=\"logo-google\" slot=\"start\" />\n }\n <ion-label color=\"danger\"> Login with Google</ion-label>\n </ion-item>\n </ion-list>\n </ion-col>\n <ion-col size=\"12\" size-md=\"6\">\n <ion-list lines=\"none\">\n <ion-item\n (click)=\"loginWith('apple.com')\"\n tappable\n [disabled]=\"!!signingWith()\"\n >\n @if (signingWith() === \"apple.com\") {\n <ion-spinner slot=\"start\" name=\"lines-small\" />\n } @else {\n <ion-icon color=\"dark\" name=\"logo-apple\" slot=\"start\" />\n }\n\n <ion-label color=\"dark\"> Login with Apple</ion-label>\n </ion-item>\n </ion-list>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col size=\"12\" size-md=\"6\">\n <ion-list lines=\"none\">\n <ion-item\n (click)=\"loginWith('microsoft.com')\"\n tappable\n [disabled]=\"!!signingWith()\"\n >\n @if (signingWith() === \"microsoft.com\") {\n <ion-spinner\n slot=\"start\"\n color=\"secondary\"\n name=\"lines-small\"\n />\n } @else {\n <ion-icon slot=\"start\" color=\"secondary\" name=\"logo-windows\" />\n }\n <ion-label color=\"secondary\">Login with Microsoft</ion-label>\n </ion-item>\n </ion-list>\n </ion-col>\n <ion-col size=\"12\" size-md=\"6\">\n <ion-list lines=\"none\">\n <ion-item\n (click)=\"loginWith('facebook.com')\"\n tappable\n [disabled]=\"!!signingWith()\"\n >\n @if (signingWith() === \"facebook.com\") {\n <ion-spinner slot=\"start\" color=\"primary\" name=\"lines-small\" />\n } @else {\n <ion-icon slot=\"start\" color=\"primary\" name=\"logo-facebook\" />\n }\n <ion-label color=\"primary\">Login with Facebook</ion-label>\n </ion-item>\n </ion-list>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col size=\"12\" size-md=\"6\">\n <ion-list lines=\"none\">\n <ion-item\n (click)=\"loginWith('github.com')\"\n tappable\n [disabled]=\"!!signingWith()\"\n >\n @if (signingWith() === \"github.com\") {\n <ion-spinner slot=\"start\" color=\"tertiary\" name=\"lines-small\" />\n } @else {\n <ion-icon slot=\"start\" color=\"tertiary\" name=\"logo-github\" />\n }\n <ion-label color=\"tertiary\">Login with GitHub</ion-label>\n </ion-item>\n </ion-list>\n </ion-col>\n </ion-row>\n </ion-grid>\n </ion-card>\n\n <p style=\"text-align: center; font-size: smaller\">\n <ion-text color=\"medium\">\n If any issues get\n <a href=\"mailto:help@sneat.app?subject=Problem+with+login+at+Sneat.app\"\n >help&#64;sneat.app</a\n >\n </ion-text>\n </p>\n</ion-content>\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sneat/auth-ui",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },