Download apps/backend/src/api/routes/users.controller.ts from Leon4gr45/postio: direct link, hf CLI and curl.
- Browser
- Download file 10.8 kB
-
https://huggingface.co/spaces/Leon4gr45/postio/resolve/main/apps/backend/src/api/routes/users.controller.ts
- Command line
-
hf download hf://spaces/Leon4gr45/postio/apps/backend/src/api/routes/users.controller.ts
-
curl -L -o users.controller.ts https://huggingface.co/spaces/Leon4gr45/postio/resolve/main/apps/backend/src/api/routes/users.controller.ts
10.8 kB
| import { | |
| Body, | |
| Controller, | |
| Get, | |
| HttpException, | |
| Post, | |
| Query, | |
| Req, | |
| Res, | |
| } from '@nestjs/common'; | |
| import { GetUserFromRequest } from '@gitroom/nestjs-libraries/user/user.from.request'; | |
| import { sign } from 'jsonwebtoken'; | |
| import { Organization, User } from '@prisma/client'; | |
| import { SubscriptionService } from '@gitroom/nestjs-libraries/database/prisma/subscriptions/subscription.service'; | |
| import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request'; | |
| import { StripeService } from '@gitroom/nestjs-libraries/services/stripe.service'; | |
| import { Response, Request } from 'express'; | |
| import { AuthService } from '@gitroom/backend/services/auth/auth.service'; | |
| import { OrganizationService } from '@gitroom/nestjs-libraries/database/prisma/organizations/organization.service'; | |
| import { CheckPolicies } from '@gitroom/backend/services/auth/permissions/permissions.ability'; | |
| import { getCookieUrlFromDomain } from '@gitroom/helpers/subdomain/subdomain.management'; | |
| import { pricing } from '@gitroom/nestjs-libraries/database/prisma/subscriptions/pricing'; | |
| import { ApiTags } from '@nestjs/swagger'; | |
| import { UsersService } from '@gitroom/nestjs-libraries/database/prisma/users/users.service'; | |
| import { UserDetailDto } from '@gitroom/nestjs-libraries/dtos/users/user.details.dto'; | |
| import { EmailNotificationsDto } from '@gitroom/nestjs-libraries/dtos/users/email-notifications.dto'; | |
| import { HttpForbiddenException } from '@gitroom/nestjs-libraries/services/exception.filter'; | |
| import { RealIP } from 'nestjs-real-ip'; | |
| import { UserAgent } from '@gitroom/nestjs-libraries/user/user.agent'; | |
| import { TrackEnum } from '@gitroom/nestjs-libraries/user/track.enum'; | |
| import { TrackService } from '@gitroom/nestjs-libraries/track/track.service'; | |
| import { makeId } from '@gitroom/nestjs-libraries/services/make.is'; | |
| import { | |
| AuthorizationActions, | |
| Sections, | |
| } from '@gitroom/backend/services/auth/permissions/permission.exception.class'; | |
| ('User') | |
| ('/user') | |
| export class UsersController { | |
| constructor( | |
| private _subscriptionService: SubscriptionService, | |
| private _stripeService: StripeService, | |
| private _authService: AuthService, | |
| private _orgService: OrganizationService, | |
| private _userService: UsersService, | |
| private _trackService: TrackService | |
| ) {} | |
| ('/chatbase-token') | |
| async getChatbaseToken( | |
| () user: User, | |
| () organization: Organization | |
| ) { | |
| if (!process.env.CHATBASE_TOKEN) { | |
| throw new HttpException('Chatbase SSO is not configured', 400); | |
| } | |
| const token = sign( | |
| { | |
| user_id: organization.id, | |
| email: user.email, | |
| ...(organization.paymentId | |
| ? { | |
| stripe_accounts: [ | |
| { | |
| label: organization.name, | |
| stripe_id: organization.paymentId, | |
| }, | |
| ], | |
| } | |
| : {}), | |
| }, | |
| process.env.CHATBASE_TOKEN, | |
| { expiresIn: '1h' } | |
| ); | |
| return { token }; | |
| } | |
| ('/agent-media-sso') | |
| async getAgentMediaSsoUrl( | |
| () user: User, | |
| () organization: Organization | |
| ) { | |
| if (!process.env.AGENT_MEDIA_SSO_KEY) { | |
| throw new HttpException('Agent Media SSO is not configured', 400); | |
| } | |
| const token = sign( | |
| { id: organization.id, displayName: organization.name }, | |
| process.env.AGENT_MEDIA_SSO_KEY | |
| ); | |
| return { url: `https://agent-media.ai/sso/${token}` }; | |
| } | |
| ('/self') | |
| async getSelf( | |
| () user: User, | |
| () organization: Organization, | |
| () req: Request | |
| ) { | |
| if (!organization) { | |
| throw new HttpForbiddenException(); | |
| } | |
| const impersonate = req.cookies.impersonate || req.headers.impersonate; | |
| // @ts-ignore | |
| return { | |
| ...user, | |
| orgId: organization.id, | |
| totalChannels: !process.env.STRIPE_PUBLISHABLE_KEY | |
| ? 10000 | |
| : // @ts-ignore | |
| organization?.subscription?.totalChannels || pricing.FREE.channel, | |
| tier: | |
| // @ts-ignore | |
| organization?.subscription?.subscriptionTier || | |
| (!process.env.STRIPE_PUBLISHABLE_KEY ? 'ULTIMATE' : 'FREE'), | |
| // @ts-ignore | |
| role: organization?.users[0]?.role, | |
| // @ts-ignore | |
| isLifetime: !!organization?.subscription?.isLifetime, | |
| admin: !!user.isSuperAdmin, | |
| impersonate: !!impersonate, | |
| isTrailing: !process.env.STRIPE_PUBLISHABLE_KEY | |
| ? false | |
| : organization?.isTrailing, | |
| allowTrial: organization?.allowTrial, | |
| streakSince: organization?.streakSince || null, | |
| publicApi: | |
| // @ts-ignore | |
| organization?.users[0]?.role === 'SUPERADMIN' || | |
| // @ts-ignore | |
| organization?.users[0]?.role === 'ADMIN' | |
| ? organization?.apiKey | |
| : '', | |
| }; | |
| } | |
| ('/personal') | |
| async getPersonalInformation(() user: User) { | |
| return this._userService.getPersonal(user.id); | |
| } | |
| ('/impersonate') | |
| async getImpersonate( | |
| () user: User, | |
| ('name') name: string | |
| ) { | |
| if (!user.isSuperAdmin) { | |
| throw new HttpException('Unauthorized', 400); | |
| } | |
| return this._userService.getImpersonateUser(name); | |
| } | |
| ('/impersonate') | |
| async setImpersonate( | |
| () user: User, | |
| ('id') id: string, | |
| ({ passthrough: true }) response: Response | |
| ) { | |
| if (!user.isSuperAdmin) { | |
| throw new HttpException('Unauthorized', 400); | |
| } | |
| response.cookie('impersonate', id, { | |
| domain: getCookieUrlFromDomain(process.env.FRONTEND_URL!), | |
| ...(!process.env.NOT_SECURED | |
| ? { | |
| secure: true, | |
| httpOnly: true, | |
| sameSite: 'none', | |
| } | |
| : {}), | |
| expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365), | |
| }); | |
| if (process.env.NOT_SECURED) { | |
| response.header('impersonate', id); | |
| } | |
| } | |
| ('/personal') | |
| async changePersonal( | |
| () user: User, | |
| () body: UserDetailDto | |
| ) { | |
| return this._userService.changePersonal(user.id, body); | |
| } | |
| ('/email-notifications') | |
| async getEmailNotifications(() user: User) { | |
| return this._userService.getEmailNotifications(user.id); | |
| } | |
| ('/email-notifications') | |
| async updateEmailNotifications( | |
| () user: User, | |
| () body: EmailNotificationsDto | |
| ) { | |
| return this._userService.updateEmailNotifications(user.id, body); | |
| } | |
| ('/api-key/rotate') | |
| ([AuthorizationActions.Create, Sections.ADMIN]) | |
| async rotateApiKey(() organization: Organization) { | |
| return this._orgService.updateApiKey(organization.id); | |
| } | |
| ('/subscription') | |
| ([AuthorizationActions.Create, Sections.ADMIN]) | |
| async getSubscription(() organization: Organization) { | |
| const subscription = | |
| await this._subscriptionService.getSubscriptionByOrganizationId( | |
| organization.id | |
| ); | |
| return subscription ? { subscription } : { subscription: undefined }; | |
| } | |
| ('/subscription/tiers') | |
| ([AuthorizationActions.Create, Sections.ADMIN]) | |
| async tiers() { | |
| return this._stripeService.getPackages(); | |
| } | |
| ('/join-org') | |
| async joinOrg( | |
| () user: User, | |
| ('org') org: string, | |
| ({ passthrough: true }) response: Response | |
| ) { | |
| const getOrgFromCookie = this._authService.getOrgFromCookie(org); | |
| if (!getOrgFromCookie) { | |
| return response.status(200).json({ id: null }); | |
| } | |
| const addedOrg = await this._orgService.addUserToOrg( | |
| user.id, | |
| getOrgFromCookie.id, | |
| getOrgFromCookie.orgId, | |
| getOrgFromCookie.role | |
| ); | |
| response.status(200).json({ | |
| id: typeof addedOrg !== 'boolean' ? addedOrg.organizationId : null, | |
| }); | |
| } | |
| ('/organizations') | |
| async getOrgs(() user: User) { | |
| return (await this._orgService.getOrgsByUserId(user.id)).filter( | |
| (f) => !f.users[0].disabled | |
| ); | |
| } | |
| ('/change-org') | |
| changeOrg( | |
| ('id') id: string, | |
| ({ passthrough: true }) response: Response | |
| ) { | |
| response.cookie('showorg', id, { | |
| domain: getCookieUrlFromDomain(process.env.FRONTEND_URL!), | |
| ...(!process.env.NOT_SECURED | |
| ? { | |
| secure: true, | |
| httpOnly: true, | |
| sameSite: 'none', | |
| } | |
| : {}), | |
| expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365), | |
| }); | |
| if (process.env.NOT_SECURED) { | |
| response.header('showorg', id); | |
| } | |
| response.status(200).send(); | |
| } | |
| ('/logout') | |
| logout(({ passthrough: true }) response: Response) { | |
| response.header('logout', 'true'); | |
| response.cookie('auth', '', { | |
| domain: getCookieUrlFromDomain(process.env.FRONTEND_URL!), | |
| ...(!process.env.NOT_SECURED | |
| ? { | |
| secure: true, | |
| httpOnly: true, | |
| sameSite: 'none', | |
| } | |
| : {}), | |
| maxAge: -1, | |
| expires: new Date(0), | |
| }); | |
| response.cookie('showorg', '', { | |
| domain: getCookieUrlFromDomain(process.env.FRONTEND_URL!), | |
| ...(!process.env.NOT_SECURED | |
| ? { | |
| secure: true, | |
| httpOnly: true, | |
| sameSite: 'none', | |
| } | |
| : {}), | |
| maxAge: -1, | |
| expires: new Date(0), | |
| }); | |
| response.cookie('impersonate', '', { | |
| domain: getCookieUrlFromDomain(process.env.FRONTEND_URL!), | |
| ...(!process.env.NOT_SECURED | |
| ? { | |
| secure: true, | |
| httpOnly: true, | |
| sameSite: 'none', | |
| } | |
| : {}), | |
| maxAge: -1, | |
| expires: new Date(0), | |
| }); | |
| response.status(200).send(); | |
| } | |
| ('/t') | |
| async trackEvent( | |
| ({ passthrough: true }) res: Response, | |
| () req: Request, | |
| () user: User, | |
| () ip: string, | |
| () userAgent: string, | |
| () | |
| body: { tt: TrackEnum; fbclid: string; additional: Record<string, any> } | |
| ) { | |
| const uniqueId = req?.cookies?.track || makeId(10); | |
| const fbclid = req?.cookies?.fbclid || body.fbclid; | |
| await this._trackService.track( | |
| uniqueId, | |
| ip, | |
| userAgent, | |
| body.tt, | |
| body.additional, | |
| fbclid, | |
| user | |
| ); | |
| if (!req.cookies.track) { | |
| res.cookie('track', uniqueId, { | |
| domain: getCookieUrlFromDomain(process.env.FRONTEND_URL!), | |
| ...(!process.env.NOT_SECURED | |
| ? { | |
| secure: true, | |
| httpOnly: true, | |
| sameSite: 'none', | |
| } | |
| : {}), | |
| expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365), | |
| }); | |
| } | |
| res.status(200).json({ | |
| track: uniqueId, | |
| }); | |
| } | |
| } | |