Skip to content

Commit

Permalink
Merge pull request #133 from DashHub-ai/feature/add-share-button
Browse files Browse the repository at this point in the history
Add share projects support
  • Loading branch information
Mati365 authored Jan 12, 2025
2 parents 316c07f + 3ab4b97 commit 0d7dd79
Show file tree
Hide file tree
Showing 164 changed files with 2,946 additions and 468 deletions.
4 changes: 4 additions & 0 deletions apps/admin/src/i18n/packs/i18n-lang-en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,10 @@ export const I18N_PACK_EN = deepmerge(I18N_FORWARDED_EN_PACK, {
label: 'E-Mail',
placeholder: 'Enter e-mail address',
},
name: {
label: 'Name and surname',
placeholder: 'Enter name and surname',
},
flags: {
label: 'Flags',
},
Expand Down
4 changes: 4 additions & 0 deletions apps/admin/src/i18n/packs/i18n-lang-pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,10 @@ export const I18N_PACK_PL: I18nLangPack = deepmerge(I18N_FORWARDED_PL_PACK, {
label: 'E-mail',
placeholder: 'Wpisz adres e-mail',
},
name: {
label: 'Imię i nazwisko',
placeholder: 'Wpisz imię i nazwisko',
},
flags: {
label: 'Flagi',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@ export function LoggedInUserItem() {
<ul className="uk-dropdown-nav uk-nav">
<li className="p-3 text-sm">
<div className="flex flex-col space-y-1.5">
<p className="text-sm font-medium leading-none uk-text-capitalize">
{session.token.role}
<p className="font-medium text-sm uk-text-capitalize leading-none">
{session.token.name}
</p>
<p className="text-xs leading-none text-muted-foreground">
<p className="text-muted-foreground text-xs leading-none">
{session.token.email}
</p>
</div>
</li>
<li className="uk-nav-divider" />
<li>
<a
className="uk-drop-close justify-between"
className="justify-between uk-drop-close"
type="button"
href=""
onClick={sdks.auth.logOut}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { SdkUserT } from '@llm/sdk';
import { Checkbox, FormField, Input } from '@llm/ui';
import { useI18n } from '~/i18n';

type Value = Pick<SdkUserT, 'email' | 'active' | 'archiveProtection'>;
type Value = Pick<SdkUserT, 'name' | 'email' | 'active' | 'archiveProtection'>;

type Props = ValidationErrorsListProps<Value>;

Expand All @@ -15,6 +15,20 @@ export const UserSharedFormFields = controlled<Value, Props>(({ errors, control:

return (
<>
<FormField
className="uk-margin"
label={t.fields.name.label}
{...validation.extract('email')}
>
<Input
name="name"
autoComplete="new-name"
placeholder={t.fields.name.placeholder}
required
{...bind.path('name')}
/>
</FormField>

<FormField
className="uk-margin"
label={t.fields.email.label}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export function UserUpdateFormModal(
active: user.active,
archiveProtection: user.archiveProtection,
auth: user.auth,
name: user.name,
email: user.email,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export function UsersTableContainer() {
createModal.showAsOptional({
defaultValue: {
email: '',
name: '',
role: 'root',
active: true,
archiveProtection: false,
Expand Down
26 changes: 26 additions & 0 deletions apps/backend/src/migrations/0033-add-name-to-users.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { Kysely } from 'kysely';

export async function up(db: Kysely<any>): Promise<void> {
await db.schema
.alterTable('users')
.addColumn('name', 'text')
.execute();

await db
.updateTable('users')
.set({ name: 'User' })
.where('name', 'is', null)
.execute();

await db.schema
.alterTable('users')
.alterColumn('name', col => col.setNotNull())
.execute();
}

export async function down(db: Kysely<any>): Promise<void> {
await db.schema
.alterTable('users')
.dropColumn('name')
.execute();
}
2 changes: 2 additions & 0 deletions apps/backend/src/migrations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import * as dropProjectPolicies from './0029-drop-project-policies';
import * as addPermissionsTable from './0030-add-permissions-table';
import * as dropPublicFlagInChats from './0031-drop-public-flag-in-chats';
import * as addTechUsersToOrganizationRoles from './0032-add-tech-users-to-organization-roles';
import * as addNameToUsers from './0033-add-name-to-users';

export const DB_MIGRATIONS = {
'0000-add-users-tables': addUsersTables,
Expand Down Expand Up @@ -66,4 +67,5 @@ export const DB_MIGRATIONS = {
'0030-add-permissions-table': addPermissionsTable,
'0031-drop-public-flag-in-chats': dropPublicFlagInChats,
'0032-add-tech-users-to-organization-roles': addTechUsersToOrganizationRoles,
'0033-add-name-to-users': addNameToUsers,
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ChatsController } from './chats.controller';
import { OrganizationsController } from './organizations.controller';
import { ProjectsController } from './projects.controller';
import { S3BucketsController } from './s3-buckets.controller';
import { ShareResourceController } from './share-resource.controller';
import { UsersGroupsController } from './users-groups.controller';
import { UsersController } from './users.controller';

Expand All @@ -23,6 +24,7 @@ export class DashboardController extends BaseController {
@inject(S3BucketsController) s3Buckets: S3BucketsController,
@inject(ChatsController) chats: ChatsController,
@inject(AIModelsController) aiModels: AIModelsController,
@inject(ShareResourceController) shareResource: ShareResourceController,
) {
super();

Expand All @@ -35,6 +37,7 @@ export class DashboardController extends BaseController {
.route('/apps', apps.router)
.route('/s3-buckets', s3Buckets.router)
.route('/chats', chats.router)
.route('/ai-models', aiModels.router);
.route('/ai-models', aiModels.router)
.route('/share-resource', shareResource.router);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ export * from './dashboard.controller';
export * from './organizations.controller';
export * from './projects.controller';
export * from './s3-buckets.controller';
export * from './share-resource.controller';
export * from './users.controller';
export * from './users-groups.controller';
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { pipe } from 'fp-ts/lib/function';
import { inject, injectable } from 'tsyringe';

import {
SdkSearchShareResourceUsersGroupsInputV,
type ShareResourceSdk,
} from '@llm/sdk';
import { ConfigService } from '~/modules/config';
import { ShareResourceService } from '~/modules/share-resource';

import {
rejectUnsafeSdkErrors,
sdkSchemaValidator,
serializeSdkResponseTE,
} from '../../helpers';
import { AuthorizedController } from '../shared/authorized.controller';

@injectable()
export class ShareResourceController extends AuthorizedController {
constructor(
@inject(ConfigService) configService: ConfigService,
@inject(ShareResourceService) shareResourceService: ShareResourceService,
) {
super(configService);

this.router
.get(
'/users-groups/search',
sdkSchemaValidator('query', SdkSearchShareResourceUsersGroupsInputV),
async context => pipe(
context.req.valid('query'),
shareResourceService.asUser(context.var.jwt).searchShareableUsersAndGroups,
rejectUnsafeSdkErrors,
serializeSdkResponseTE<ReturnType<ShareResourceSdk['searchUsersAndGroups']>>(context),
),
);
}
}
15 changes: 7 additions & 8 deletions apps/backend/src/modules/apps/apps.firewall.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { taskEither as TE } from 'fp-ts';
import { flow, pipe } from 'fp-ts/lib/function';

import {
dropSdkPaginationPermissionsKeysIfNotCreator,
dropSdkPermissionsKeyIfNotCreator,
type SdkCreateAppInputT,
type SdkJwtTokenT,
type SdkUpdateAppInputT,
import type {
SdkCreateAppInputT,
SdkJwtTokenT,
SdkUpdateAppInputT,
} from '@llm/sdk';

import { AuthFirewallService } from '~/modules/auth/firewall';

import type { ChatsService } from '../chats';
Expand All @@ -29,15 +28,15 @@ export class AppsFirewall extends AuthFirewallService {
get = flow(
this.appsService.get,
this.permissionsService.asUser(this.jwt).chainValidateResultOrRaiseUnauthorized,
TE.map(dropSdkPermissionsKeyIfNotCreator(this.userId)),
TE.chainW(this.permissionsService.asUser(this.jwt).dropSdkPermissionsKeyIfNotCreator),
);

search = (filters: EsAppsInternalFilters) => pipe(
filters,
this.permissionsService.asUser(this.jwt).enforcePermissionsFilters,
TE.chainEitherKW(this.permissionsService.asUser(this.jwt).enforceOrganizationScopeFilters),
TE.chainW(this.appsService.search),
TE.map(dropSdkPaginationPermissionsKeysIfNotCreator(this.userId)),
TE.chainW(this.permissionsService.asUser(this.jwt).dropSdkPaginationPermissionsKeysIfNotCreator),
);

unarchive = (id: TableId) => pipe(
Expand Down
3 changes: 2 additions & 1 deletion apps/backend/src/modules/auth/services/auth-jwt.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export class AuthJWTService {
TE.chain(() => this.usersRepo.findWithRelationsById({
id: userId,
})),
TE.map(({ email, organization, role, jwtRefreshToken }) => {
TE.map(({ email, name, organization, role, jwtRefreshToken }) => {
const { jwt } = this.configService.config.auth;

const jwtRoleSpecific: SdkJwtTokenRoleSpecificT = (() => {
Expand All @@ -62,6 +62,7 @@ export class AuthJWTService {
iat: Date.now(),
exp: Date.now() + jwt.expiresIn * 1000,
email,
name,
...jwtRoleSpecific,
};

Expand Down
32 changes: 16 additions & 16 deletions apps/backend/src/modules/chats/chats.firewall.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { taskEither as TE } from 'fp-ts';
import { flow, pipe } from 'fp-ts/lib/function';

import type {
SdkCreateChatInputT,
SdkJwtTokenT,
SdkSearchChatsInputT,
SdkUpdateChatInputT,
} from '@llm/sdk';
import type { PermissionsService } from '~/modules/permissions';

import {
dropSdkPaginationPermissionsKeysIfNotCreator,
dropSdkPermissionsKeyIfNotCreator,
type SdkCreateChatInputT,
type SdkJwtTokenT,
type SdkSearchChatsInputT,
type SdkUpdateChatInputT,
} from '@llm/sdk';
import { AuthFirewallService } from '~/modules/auth/firewall';

import type { TableRowWithUuid, TableUuid } from '../database';
Expand All @@ -30,7 +28,7 @@ export class ChatsFirewall extends AuthFirewallService {
get = flow(
this.chatsService.get,
this.permissionsService.asUser(this.jwt).chainValidateResultOrRaiseUnauthorized,
TE.map(dropSdkPermissionsKeyIfNotCreator(this.userId)),
TE.chainW(this.permissionsService.asUser(this.jwt).dropSdkPermissionsKeyIfNotCreator),
);

unarchive = (id: TableUuid) => pipe(
Expand Down Expand Up @@ -60,17 +58,19 @@ export class ChatsFirewall extends AuthFirewallService {
this.permissionsService.asUser(this.jwt).enforcePermissionsFilters,
TE.chainEitherKW(this.permissionsService.asUser(this.jwt).enforceOrganizationScopeFilters),
TE.chainW(this.chatsService.search),
TE.map(dropSdkPaginationPermissionsKeysIfNotCreator(this.userId)),
TE.chainW(this.permissionsService.asUser(this.jwt).dropSdkPaginationPermissionsKeysIfNotCreator),
);

create = (dto: SdkCreateChatInputT) => pipe(
TE.Do,
TE.chainW(() => dto.project
? this.permissionsService.asUser(this.jwt).findRecordAndCheckPermissions({
accessLevel: 'write',
findRecord: this.projectsService.get(dto.project.id),
})
: TE.of(undefined)),
TE.chainW(() => (
dto.project
? this.permissionsService.asUser(this.jwt).findRecordAndCheckPermissions({
accessLevel: 'write',
findRecord: this.projectsService.get(dto.project.id),
})
: TE.of(undefined)
)),
TE.chainEitherKW(() => this.permissionsService.asUser(this.jwt).enforceOrganizationCreatorScope(dto)),
TE.chainW(mappedDto => this.chatsService.create(mappedDto)),
);
Expand Down
Loading

0 comments on commit 0d7dd79

Please sign in to comment.