diff --git a/frontend/src/lib/components/TenantUsersList/TenantUsersList.svelte b/frontend/src/lib/components/TenantUsersList/TenantUsersList.svelte
new file mode 100644
index 0000000..5a01366
--- /dev/null
+++ b/frontend/src/lib/components/TenantUsersList/TenantUsersList.svelte
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+ {#each tenantUsers as user}
+
+ {user.firstName + ' ' + user.lastName}
+ {user.email}
+
+ {/each}
+
+
+
+
diff --git a/frontend/src/lib/components/Tenants/Tenants.svelte b/frontend/src/lib/components/Tenants/Tenants.svelte
index acdfc1e..6dc94fe 100644
--- a/frontend/src/lib/components/Tenants/Tenants.svelte
+++ b/frontend/src/lib/components/Tenants/Tenants.svelte
@@ -1,19 +1,18 @@
{#if tenants}
-
-
- {#each tenants as tenant}
-
-
-
- {/each}
-
-
+
+ {#each tenants as tenant}
+
+
+
+ {/each}
+
{/if}
diff --git a/frontend/src/lib/context/TenantUsersContext/TenantUsers.ts b/frontend/src/lib/context/TenantUsersContext/TenantUsers.ts
new file mode 100644
index 0000000..ac837ae
--- /dev/null
+++ b/frontend/src/lib/context/TenantUsersContext/TenantUsers.ts
@@ -0,0 +1,14 @@
+import { z } from 'zod';
+
+// const StatusSchema = z.union([z.literal('ENABLED'), z.literal('DISABLED')]);
+
+export const TenantUserSchema = z.object({
+ id: z.number(),
+ email: z.string(),
+ // password: z.string(),
+ // status: StatusSchema,
+ firstName: z.string(),
+ lastName: z.string()
+});
+
+export type TenantUser = z.infer;
diff --git a/frontend/src/lib/context/UnityAuthContext.ts b/frontend/src/lib/context/UnityAuthContext.ts
index 365e121..4d3975e 100644
--- a/frontend/src/lib/context/UnityAuthContext.ts
+++ b/frontend/src/lib/context/UnityAuthContext.ts
@@ -39,9 +39,12 @@ export function createUnityAuthContext(props: UnityAuthContextProviderProps & Un
...props.unityAuthServiceProps
});
+ unityAuthService.setAuthInfo(unityAuthService.getLoginData());
const user: Writable = writable(unityAuthService.getLoginData());
unityAuthService.subscribe('login', (args) => user.set(args));
unityAuthService.subscribe('logout', () => user.set(undefined));
+ unityAuthService.subscribe('login', (args) => unityAuthService.setAuthInfo(args));
+ unityAuthService.subscribe('logout', () => unityAuthService.setAuthInfo(undefined));
function alertError(unknown: unknown) {
console.error(unknown);
diff --git a/frontend/src/lib/services/TenantsResolver/shared.ts b/frontend/src/lib/services/TenantsResolver/shared.ts
index dc2a763..61748d9 100644
--- a/frontend/src/lib/services/TenantsResolver/shared.ts
+++ b/frontend/src/lib/services/TenantsResolver/shared.ts
@@ -1,13 +1,13 @@
import { z } from 'zod';
-export const TenantsSchema = z.object({
+export const TenantSchema = z.object({
id: z.number(),
name: z.string()
});
-export type Tenants = z.infer;
+export type Tenant = z.infer;
-export const TenantsSuccessResponseSchema = z.array(TenantsSchema);
+export const TenantsSuccessResponseSchema = z.array(TenantSchema);
export type TenantsSuccessResponse = z.infer;
diff --git a/frontend/src/lib/services/UnityAuth/UnityAuth.ts b/frontend/src/lib/services/UnityAuth/UnityAuth.ts
index 84c447e..c2245dd 100644
--- a/frontend/src/lib/services/UnityAuth/UnityAuth.ts
+++ b/frontend/src/lib/services/UnityAuth/UnityAuth.ts
@@ -1,8 +1,14 @@
import type { AxiosInstance } from 'axios';
import { BaseObservable } from '../EventBus/EventBus';
-import type { CompleteLoginResponse, UnityAuthServiceProps } from './shared';
+import type {
+ CompleteLoginResponse,
+ GetTenantUsersResponse,
+ UnityAuthLoginResponse,
+ UnityAuthServiceProps
+} from './shared';
import {
CompleteLoginResponseSchema,
+ GetTenantUsersResponseSchema,
UnityAuthLoginResponseSchema,
UnityAuthServicePropsSchema
} from './shared';
@@ -20,12 +26,15 @@ export type UnityAuthService = BaseObservable & {
login(email: string, password: string): Promise;
getLoginData(): CompleteLoginResponse | undefined;
logout(): void;
+ getTenantUsers(id: number): Promise;
+ setAuthInfo(authInfo: UnityAuthLoginResponse | undefined): void;
};
export class UnityAuthServiceImpl
extends BaseObservable
implements UnityAuthService
{
+ private authTokenInterceptorId: number = -1;
private loginDataKey: string = 'loginData';
private axiosInstance: AxiosInstance;
private tenantsResolver: TenantsResolver;
@@ -91,6 +100,22 @@ export class UnityAuthServiceImpl
return CompleteLoginResponseSchema.parse(JSON.parse(loginInfo));
}
}
+
+ async getTenantUsers(id: number): Promise {
+ const res = await this.axiosInstance.get(`/api/tenants/${id}/users`);
+ return GetTenantUsersResponseSchema.parse(res.data);
+ }
+
+ setAuthInfo(authInfo: UnityAuthLoginResponse | undefined): void {
+ if (authInfo) {
+ this.authTokenInterceptorId = this.axiosInstance.interceptors.request.use(function (config) {
+ config.headers['Authorization'] = `Bearer ${authInfo.access_token}`;
+ return config;
+ });
+ } else {
+ this.axiosInstance.interceptors.request.eject(this.authTokenInterceptorId);
+ }
+ }
}
export function unityAuthServiceFactory(props: UnityAuthServiceProps): UnityAuthService {
diff --git a/frontend/src/lib/services/UnityAuth/shared.ts b/frontend/src/lib/services/UnityAuth/shared.ts
index 3e5e9b3..d45d2b7 100644
--- a/frontend/src/lib/services/UnityAuth/shared.ts
+++ b/frontend/src/lib/services/UnityAuth/shared.ts
@@ -1,6 +1,7 @@
import { z } from 'zod';
import type { TenantsResolver } from '../TenantsResolver/TenantsResolver';
-import { TenantsSchema } from '../TenantsResolver/shared';
+import { TenantSchema } from '../TenantsResolver/shared';
+import { TenantUserSchema } from '$lib/context/TenantUsersContext/TenantUsers';
export const UnityAuthServicePropsSchema = z.object({
baseURL: z.string()
@@ -15,7 +16,7 @@ export const UnityAuthLoginResponseSchema = z.object({
token_type: z.string(),
expires_in: z.number(),
username: z.string(),
- tenants: z.array(TenantsSchema).optional()
+ tenants: z.array(TenantSchema).optional()
});
export type UnityAuthLoginResponse = z.infer;
@@ -23,3 +24,10 @@ export type UnityAuthLoginResponse = z.infer;
+
+export const GetTenantUsersResponseSchema = z.array(TenantUserSchema);
+export type GetTenantUsersResponse = z.infer;
+
+export type TenantUsersResponse = {
+ tenantUsers: GetTenantUsersResponse;
+};
diff --git a/frontend/src/lib/utils/types.ts b/frontend/src/lib/utils/types.ts
new file mode 100644
index 0000000..0622161
--- /dev/null
+++ b/frontend/src/lib/utils/types.ts
@@ -0,0 +1,4 @@
+export type Maybe = T | undefined | null;
+export type HasId = {
+ id: T;
+};
diff --git a/frontend/src/routes/tenant/+layout.svelte b/frontend/src/routes/tenant/+layout.svelte
index e203a32..58cba2f 100644
--- a/frontend/src/routes/tenant/+layout.svelte
+++ b/frontend/src/routes/tenant/+layout.svelte
@@ -1,13 +1,27 @@
-
-
+
+ {#if $user && $user.tenants}
+
+ {/if}
+
+
+
diff --git a/frontend/src/routes/tenant/[tenant_id]/+page.svelte b/frontend/src/routes/tenant/[tenant_id]/+page.svelte
new file mode 100644
index 0000000..97d2f52
--- /dev/null
+++ b/frontend/src/routes/tenant/[tenant_id]/+page.svelte
@@ -0,0 +1,33 @@
+
+
+
+ {#if tenantUsers}
+
+
+
+ {/if}
+
+
+