From e7ab0eb787caae6e38f3f1123a401a6b209121a5 Mon Sep 17 00:00:00 2001 From: Anand Chowdhary Date: Mon, 3 Aug 2020 00:24:57 +0530 Subject: [PATCH] :recycle: Change organization to group --- README.md | 2 +- src/_staart/helpers/authorization.ts | 52 +- src/_staart/helpers/jwt.ts | 2 +- src/_staart/helpers/middleware.ts | 4 +- src/_staart/helpers/tracking.ts | 2 +- src/_staart/helpers/utils.ts | 10 +- src/_staart/helpers/webhooks.ts | 18 +- src/_staart/interfaces/enum.ts | 22 +- src/_staart/interfaces/general.ts | 2 +- src/_staart/rest/admin.ts | 10 +- src/_staart/rest/auth.ts | 14 +- src/_staart/rest/organization.ts | 795 ++++++------------ src/_staart/rest/user.ts | 31 +- src/_staart/services/organization.service.ts | 95 +-- src/_staart/services/user.service.ts | 2 +- src/controllers/admin/index.ts | 2 +- src/controllers/auth/index.ts | 4 +- src/controllers/organizations/_id/api-keys.ts | 16 +- src/controllers/organizations/_id/billing.ts | 38 +- src/controllers/organizations/_id/domains.ts | 16 +- src/controllers/organizations/_id/index.ts | 40 +- src/controllers/organizations/_id/invoices.ts | 21 +- .../organizations/_id/memberships.ts | 45 +- src/controllers/organizations/_id/sources.ts | 46 +- .../organizations/_id/subscriptions.ts | 38 +- .../organizations/_id/transactions.ts | 29 +- src/controllers/organizations/_id/webhooks.ts | 14 +- src/controllers/organizations/index.ts | 2 +- 28 files changed, 503 insertions(+), 869 deletions(-) diff --git a/README.md b/README.md index 0d4c37afc..390d3c8f6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![Staart API](https://raw.githubusercontent.com/staart/staart.js.org/master/assets/svg/api.svg?sanitize=true)](https://staart.js.org/api) -Staart API is a Node.js backend starter for SaaS startups written in TypeScript. It has all the features you need to build a SaaS product, like user management and authentication, billing, organizations, GDPR tools, API keys, rate limiting, superadmin impersonation, and more. +Staart API is a Node.js backend starter for SaaS startups written in TypeScript. It has all the features you need to build a SaaS product, like user management and authentication, billing, groups, GDPR tools, API keys, rate limiting, superadmin impersonation, and more. **⚠️ v3 BETA WARNING:** This is a fork of [Staart API](https://github.com/staart/api) with experimental changes. diff --git a/src/_staart/helpers/authorization.ts b/src/_staart/helpers/authorization.ts index 3df32ea6b..3c03fc9c9 100644 --- a/src/_staart/helpers/authorization.ts +++ b/src/_staart/helpers/authorization.ts @@ -7,14 +7,14 @@ import { OrgScopes, Tokens, UserScopes, SudoScopes } from "../interfaces/enum"; import { ApiKeyResponse, AccessTokenResponse } from "./jwt"; import { users, - organizations, + groups, memberships, accessTokens, apiKeys, } from "@prisma/client"; import { prisma } from "./prisma"; import { getUserById } from "../services/user.service"; -import { getOrganizationById } from "../services/organization.service"; +import { getOrganizationById } from "../services/group.service"; /** * Whether a user can perform an action on another user @@ -44,7 +44,7 @@ const canUserUser = async (user: users, action: UserScopes, target: users) => { }); similarMemberships.forEach((similarMembership) => { - // A user can read another user in the same organization, as long as they're not a basic member + // A user can read another user in the same group, as long as they're not a basic member if (action === UserScopes.READ_USER) if (userMemberships[similarMembership].role) allowed = true; }); @@ -53,7 +53,7 @@ const canUserUser = async (user: users, action: UserScopes, target: users) => { }; /** - * Whether an access token can perform an action for an organization + * Whether an access token can perform an action for an group */ const canAccessTokenUser = ( accessToken: accessTokens, @@ -70,33 +70,31 @@ const canAccessTokenUser = ( }; /** - * Whether a user can perform an action on an organization + * Whether a user can perform an action on an group */ const canUserOrganization = async ( user: users, action: OrgScopes, - target: organizations + target: groups ) => { // A super user can do anything if (user.role === "SUDO") return true; const memberships = await prisma.memberships.findMany({ where: { user } }); - const targetMemberships = memberships.filter( - (m) => m.organizationId === target.id - ); + const targetMemberships = memberships.filter((m) => m.groupId === target.id); let allowed = false; targetMemberships.forEach((membership) => { - // An organization owner can do anything + // An group owner can do anything if (membership.role === "OWNER") allowed = true; - // An organization admin can do anything too + // An group admin can do anything too if (membership.role === "ADMIN") allowed = true; - // An organization reseller can do anything too + // An group reseller can do anything too if (membership.role === "RESELLER") allowed = true; - // An organization member can read, not edit/delete/invite + // An group member can read, not edit/delete/invite if ( membership.role === "MEMBER" && (action === OrgScopes.READ_ORG || @@ -130,7 +128,7 @@ const canUserMembership = async ( memberships.forEach((membership) => { // An admin, owner, or reseller can edit if ( - membership.organizationId === target.organizationId && + membership.groupId === target.groupId && (membership.role === "OWNER" || membership.role === "ADMIN" || membership.role === "RESELLER") @@ -139,7 +137,7 @@ const canUserMembership = async ( // Another member can view if ( - membership.organizationId === target.organizationId && + membership.groupId === target.groupId && membership.role === "MEMBER" && action === OrgScopes.READ_ORG_MEMBERSHIPS ) @@ -160,15 +158,15 @@ const canUserSudo = async (user: users, action: SudoScopes) => { }; /** - * Whether an API key can perform an action for an organization + * Whether an API key can perform an action for an group */ const canApiKeyOrganization = ( apiKey: apiKeys, action: OrgScopes, - target: organizations + target: groups ) => { - // An API key can only work in its own organization - if (apiKey.organizationId !== target.id) return false; + // An API key can only work in its own group + if (apiKey.groupId !== target.id) return false; // If it has no scopes, it has no permissions if (!apiKey.scopes) return false; @@ -184,8 +182,8 @@ const canApiKeyOrganization = ( export const can = async ( user: string | users | ApiKeyResponse | AccessTokenResponse, action: OrgScopes | UserScopes | SudoScopes, - targetType: "user" | "organization" | "membership" | "sudo", - target?: string | users | organizations | memberships + targetType: "user" | "group" | "membership" | "sudo", + target?: string | users | groups | memberships ) => { let requestFromType: "users" | "apiKeys" | "accessTokens" = "users"; @@ -217,9 +215,9 @@ export const can = async ( }); if (!membership) throw new Error(USER_NOT_FOUND); target = membership; - } else if (targetType === "organization") { - const organization = await getOrganizationById(target); - target = organization; + } else if (targetType === "group") { + const group = await getOrganizationById(target); + target = group; } else { // Target is a user if (requestFromType === "users" && user.id === parseInt(target)) { @@ -240,7 +238,7 @@ export const can = async ( return canApiKeyOrganization( apiKeyDetails, action as OrgScopes, - target as organizations + target as groups ); } else if (requestFromType === "accessTokens") { const accessTokenDetails = await prisma.accessTokens.findOne({ @@ -261,11 +259,11 @@ export const can = async ( action as UserScopes | OrgScopes, target as memberships ); - } else if (targetType === "organization") { + } else if (targetType === "group") { return canUserOrganization( user as users, action as OrgScopes, - target as organizations + target as groups ); } } diff --git a/src/_staart/helpers/jwt.ts b/src/_staart/helpers/jwt.ts index 88ad0deea..c3793b44b 100644 --- a/src/_staart/helpers/jwt.ts +++ b/src/_staart/helpers/jwt.ts @@ -74,7 +74,7 @@ export interface TokenResponse { } export interface ApiKeyResponse { id: string; - organizationId: string; + groupId: string; scopes: string; jti: string; sub: Tokens.API_KEY; diff --git a/src/_staart/helpers/middleware.ts b/src/_staart/helpers/middleware.ts index 5ff726088..c10f6ec88 100644 --- a/src/_staart/helpers/middleware.ts +++ b/src/_staart/helpers/middleware.ts @@ -181,7 +181,7 @@ export const rateLimitHandler = async ( if (apiKey) { try { const details = await verifyToken(apiKey, Tokens.API_KEY); - if (details.organizationId) { + if (details.groupId) { res.setHeader("X-Rate-Limit-Type", "api-key"); return rateLimiter(req, res, next); } @@ -203,7 +203,7 @@ export const speedLimitHandler = async ( if (apiKey) { try { const details = await verifyToken(apiKey, Tokens.API_KEY); - if (details.organizationId) { + if (details.groupId) { res.setHeader("X-Rate-Limit-Type", "api-key"); return next(); } diff --git a/src/_staart/helpers/tracking.ts b/src/_staart/helpers/tracking.ts index 97f8d310a..b277a8e0c 100644 --- a/src/_staart/helpers/tracking.ts +++ b/src/_staart/helpers/tracking.ts @@ -47,7 +47,7 @@ export const trackUrl = async (req: Request, res: Response) => { Tokens.API_KEY ); trackingObject.apiKeyId = token.id; - trackingObject.apiKeyOrganizationId = token.organizationId; + trackingObject.apiKeyOrganizationId = token.groupId; trackingObject.apiKeyJti = token.jti; delete trackingObject.apiKey; } catch (error) { diff --git a/src/_staart/helpers/utils.ts b/src/_staart/helpers/utils.ts index 0fcb324a4..c98859194 100644 --- a/src/_staart/helpers/utils.ts +++ b/src/_staart/helpers/utils.ts @@ -7,7 +7,7 @@ import { Tokens } from "../interfaces/enum"; import { ApiKeyResponse } from "./jwt"; import { users } from "@prisma/client"; import { prisma } from "../helpers/prisma"; -import { getOrganizationById } from "../services/organization.service"; +import { getOrganizationById } from "../services/group.service"; import { getUserById } from "../services/user.service"; /** @@ -25,9 +25,9 @@ export const deleteSensitiveInfoUser = (user: users) => { return user; }; -export const organizationUsernameToId = async (id: string) => { +export const groupUsernameToId = async (id: string) => { const result = ( - await prisma.organizations.findOne({ + await prisma.groups.findOne({ select: { id: true }, where: { username: id, @@ -114,7 +114,7 @@ export const readOnlyValues = [ "id", "jwtApiKey", "userId", - "organizationId", + "groupId", ]; /** @@ -123,7 +123,7 @@ export const readOnlyValues = [ export const IdValues = [ "id", "userId", - "organizationId", + "groupId", "primaryEmail", "apiKeyId", "apiKeyOrganizationId", diff --git a/src/_staart/helpers/webhooks.ts b/src/_staart/helpers/webhooks.ts index a4528c5ec..03cbb6e25 100644 --- a/src/_staart/helpers/webhooks.ts +++ b/src/_staart/helpers/webhooks.ts @@ -19,7 +19,7 @@ const setupQueue = async () => { }; export const queueWebhook = ( - organizationId: string, + groupId: string, webhook: Webhooks, data?: any ) => { @@ -28,7 +28,7 @@ export const queueWebhook = ( redisQueue.sendMessageAsync({ qname: WEBHOOK_QUEUE, message: JSON.stringify({ - organizationId, + groupId, webhook, data, tryNumber: 1, @@ -46,30 +46,30 @@ export const receiveWebhookMessage = async () => { }); if ("id" in result) { const { - organizationId, + groupId, webhook, data, tryNumber, }: { tryNumber: number; - organizationId: string; + groupId: string; webhook: Webhooks; data?: any; } = JSON.parse(result.message); if (tryNumber && tryNumber > 3) { - logError("Webhook", `Unable to fire: ${organizationId} ${webhook}`); + logError("Webhook", `Unable to fire: ${groupId} ${webhook}`); return redisQueue.deleteMessageAsync({ qname: WEBHOOK_QUEUE, id: result.id, }); } try { - safeFireWebhook(organizationId, webhook, data); + safeFireWebhook(groupId, webhook, data); } catch (error) { await redisQueue.sendMessageAsync({ qname: WEBHOOK_QUEUE, message: JSON.stringify({ - organizationId, + groupId, webhook, data, tryNumber: tryNumber + 1, @@ -85,12 +85,12 @@ export const receiveWebhookMessage = async () => { }; const safeFireWebhook = async ( - organizationId: string, + groupId: string, webhook: Webhooks, data?: any ) => { const webhooksToFire = await prisma.webhooks.findMany({ - where: { organizationId: parseInt(organizationId), event: webhook }, + where: { groupId: parseInt(groupId), event: webhook }, }); for await (const hook of webhooksToFire) { try { diff --git a/src/_staart/interfaces/enum.ts b/src/_staart/interfaces/enum.ts index 28b112163..b7907fce3 100644 --- a/src/_staart/interfaces/enum.ts +++ b/src/_staart/interfaces/enum.ts @@ -10,9 +10,9 @@ export enum EventType { AUTH_PASSWORD_CHANGED = "auth.password_changed", AUTH_PASSWORD_RESET_REQUESTED = "auth.passwordReset", AUTH_APPROVE_LOCATION = "auth.approveLocation", - ORGANIZATION_CREATED = "organization.created", - ORGANIZATION_UPDATED = "organization.updated", - ORGANIZATION_DELETED = "organization.deleted", + ORGANIZATION_CREATED = "group.created", + ORGANIZATION_UPDATED = "group.updated", + ORGANIZATION_DELETED = "group.deleted", EMAIL_CREATED = "email.created", EMAIL_UPDATED = "email.updated", EMAIL_DELETED = "email.deleted", @@ -123,14 +123,14 @@ export enum UserScopes { export enum Webhooks { ALL_EVENTS = "*", - UPDATE_ORGANIZATION = "update-organization", - DELETE_ORGANIZATION = "delete-organization", - UPDATE_ORGANIZATION_BILLING = "update-organization-billing", - UPDATE_ORGANIZATION_SUBSCRIPTION = "update-organization-subscription", - CREATE_ORGANIZATION_SUBSCRIPTION = "create-organization-subscription", - DELETE_ORGANIZATION_SOURCE = "delete-organization-source", - UPDATE_ORGANIZATION_SOURCE = "update-organization-source", - CREATE_ORGANIZATION_SOURCE = "create-organization-source", + UPDATE_ORGANIZATION = "update-group", + DELETE_ORGANIZATION = "delete-group", + UPDATE_ORGANIZATION_BILLING = "update-group-billing", + UPDATE_ORGANIZATION_SUBSCRIPTION = "update-group-subscription", + CREATE_ORGANIZATION_SUBSCRIPTION = "create-group-subscription", + DELETE_ORGANIZATION_SOURCE = "delete-group-source", + UPDATE_ORGANIZATION_SOURCE = "update-group-source", + CREATE_ORGANIZATION_SOURCE = "create-group-source", UPDATE_API_KEY = "update-api-key", CREATE_API_KEY = "create-api-key", DELETE_API_KEY = "delete-api-key", diff --git a/src/_staart/interfaces/general.ts b/src/_staart/interfaces/general.ts index 3eda9ba5c..c1bbfcd72 100644 --- a/src/_staart/interfaces/general.ts +++ b/src/_staart/interfaces/general.ts @@ -33,7 +33,7 @@ export interface Event { date?: Date; ipAddress?: string; userAgent?: string; - organizationId?: number | string; + groupId?: number | string; userId?: number | string; type?: string; data?: any; diff --git a/src/_staart/rest/admin.ts b/src/_staart/rest/admin.ts index a5ba3f6d5..9c73ee5f3 100644 --- a/src/_staart/rest/admin.ts +++ b/src/_staart/rest/admin.ts @@ -15,10 +15,10 @@ import { import { getEvents } from "@staart/payments"; import { couponCodeJwt } from "../helpers/jwt"; import { - organizationsSelect, - organizationsInclude, - organizationsOrderByInput, - organizationsWhereUniqueInput, + groupsSelect, + groupsInclude, + groupsOrderByInput, + groupsWhereUniqueInput, usersSelect, usersInclude, usersOrderByInput, @@ -32,7 +32,7 @@ export const getAllOrganizationForUser = async ( ) => { if (await can(tokenUserId, SudoScopes.READ, "sudo")) return paginatedResult( - await prisma.organizations.findMany(queryParamsToSelect(queryParams)), + await prisma.groups.findMany(queryParamsToSelect(queryParams)), { first: queryParams.first, last: queryParams.last } ); throw new Error(INSUFFICIENT_PERMISSION); diff --git a/src/_staart/rest/auth.ts b/src/_staart/rest/auth.ts index 5f6524895..3087e9b35 100644 --- a/src/_staart/rest/auth.ts +++ b/src/_staart/rest/auth.ts @@ -45,7 +45,7 @@ import { users, backup_codes, } from "@prisma/client"; -import { getDomainByDomainName } from "../services/organization.service"; +import { getDomainByDomainName } from "../services/group.service"; import { PartialBy } from "../helpers/utils"; export const validateRefreshToken = async (token: string, locals: Locals) => { @@ -125,7 +125,7 @@ export const register = async ( _user: PartialBy, "username">, locals?: Locals, email?: string, - organizationId?: string, + groupId?: string, role?: MembershipRole, emailVerified = false ) => { @@ -140,23 +140,23 @@ export const register = async ( if (user.username && !(await checkUserUsernameAvailability(user.username))) throw new Error(USERNAME_EXISTS); user.username = user.username || (await getBestUsernameForUser(user.name)); - if (!organizationId && email) { + if (!groupId && email) { let domain = ""; try { domain = email.split("@")[1]; const domainDetails = await getDomainByDomainName(domain); - organizationId = domainDetails.organizationId.toString(); + groupId = domainDetails.groupId.toString(); } catch (error) {} } const userId = ( await createUser({ ...user, - ...(organizationId + ...(groupId ? { memberships: { create: { - organization: { - connect: { id: parseInt(organizationId) }, + group: { + connect: { id: parseInt(groupId) }, }, role, }, diff --git a/src/_staart/rest/organization.ts b/src/_staart/rest/organization.ts index 39f5a4fb5..3161f89b2 100644 --- a/src/_staart/rest/organization.ts +++ b/src/_staart/rest/organization.ts @@ -57,8 +57,8 @@ import { queryParamsToSelect, } from "../helpers/prisma"; import { - organizationsCreateInput, - organizationsUpdateInput, + groupsCreateInput, + groupsUpdateInput, membershipsInclude, membershipsSelect, membershipsOrderByInput, @@ -91,7 +91,7 @@ import { checkDomainAvailability, getOrganizationById, createOrganization, -} from "../services/organization.service"; +} from "../services/group.service"; import { randomString } from "@staart/text"; import { fireSingleWebhook } from "../helpers/webhooks"; import { getUserById } from "../services/user.service"; @@ -99,40 +99,40 @@ import { deleteItemFromCache } from "../helpers/cache"; export const getOrganizationForUser = async ( userId: string | ApiKeyResponse, - organizationId: string + groupId: string ) => { - if (await can(userId, OrgScopes.READ_ORG, "organization", organizationId)) - return getOrganizationById(organizationId); + if (await can(userId, OrgScopes.READ_ORG, "group", groupId)) + return getOrganizationById(groupId); throw new Error(INSUFFICIENT_PERMISSION); }; export const newOrganizationForUser = async ( userId: string, - organization: organizationsCreateInput, + group: groupsCreateInput, locals: Locals ) => { - if (!(organization.name || "").trim()) { + if (!(group.name || "").trim()) { const user = await getUserById(userId); - organization.name = user.name; + group.name = user.name; } - return createOrganization(organization, userId); + return createOrganization(group, userId); }; export const updateOrganizationForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, - data: organizationsUpdateInput, + groupId: string, + data: groupsUpdateInput, locals: Locals ) => { - if (await can(userId, OrgScopes.UPDATE_ORG, "organization", organizationId)) { - const result = await prisma.organizations.update({ + if (await can(userId, OrgScopes.UPDATE_ORG, "group", groupId)) { + const result = await prisma.groups.update({ where: { - id: parseInt(organizationId), + id: parseInt(groupId), }, data, }); - queueWebhook(organizationId, Webhooks.UPDATE_ORGANIZATION, data); - trackEvent({ organizationId, type: Webhooks.UPDATE_ORGANIZATION }, locals); + queueWebhook(groupId, Webhooks.UPDATE_ORGANIZATION, data); + trackEvent({ groupId, type: Webhooks.UPDATE_ORGANIZATION }, locals); return result; } throw new Error(INSUFFICIENT_PERMISSION); @@ -140,24 +140,24 @@ export const updateOrganizationForUser = async ( export const deleteOrganizationForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, locals: Locals ) => { - if (await can(userId, OrgScopes.DELETE_ORG, "organization", organizationId)) { - const organizationDetails = await getOrganizationById(organizationId); + if (await can(userId, OrgScopes.DELETE_ORG, "group", groupId)) { + const groupDetails = await getOrganizationById(groupId); await deleteItemFromCache( - `cache_getOrganizationById_${organizationDetails.id}`, - `cache_getOrganizationByUsername_${organizationDetails.username}` + `cache_getOrganizationById_${groupDetails.id}`, + `cache_getOrganizationByUsername_${groupDetails.username}` ); - if (organizationDetails.stripeCustomerId) - await deleteCustomer(organizationDetails.stripeCustomerId); - await prisma.organizations.delete({ + if (groupDetails.stripeCustomerId) + await deleteCustomer(groupDetails.stripeCustomerId); + await prisma.groups.delete({ where: { - id: parseInt(organizationId), + id: parseInt(groupId), }, }); - queueWebhook(organizationId, Webhooks.DELETE_ORGANIZATION); - trackEvent({ organizationId, type: Webhooks.DELETE_ORGANIZATION }, locals); + queueWebhook(groupId, Webhooks.DELETE_ORGANIZATION); + trackEvent({ groupId, type: Webhooks.DELETE_ORGANIZATION }, locals); return; } throw new Error(INSUFFICIENT_PERMISSION); @@ -165,20 +165,12 @@ export const deleteOrganizationForUser = async ( export const getOrganizationBillingForUser = async ( userId: string | ApiKeyResponse, - organizationId: string + groupId: string ) => { - if ( - await can( - userId, - OrgScopes.READ_ORG_BILLING, - "organization", - organizationId - ) - ) { - const organization = await getOrganizationById(organizationId); - if (!organization) throw new Error(ORGANIZATION_NOT_FOUND); - if (organization.stripeCustomerId) - return getCustomer(organization.stripeCustomerId); + if (await can(userId, OrgScopes.READ_ORG_BILLING, "group", groupId)) { + const group = await getOrganizationById(groupId); + if (!group) throw new Error(ORGANIZATION_NOT_FOUND); + if (group.stripeCustomerId) return getCustomer(group.stripeCustomerId); throw new Error(STRIPE_NO_CUSTOMER); } throw new Error(INSUFFICIENT_PERMISSION); @@ -186,41 +178,31 @@ export const getOrganizationBillingForUser = async ( export const updateOrganizationBillingForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, data: any, locals: Locals ) => { - if ( - await can( - userId, - OrgScopes.UPDATE_ORG_BILLING, - "organization", - organizationId - ) - ) { - const organization = await getOrganizationById(organizationId); - if (!organization) throw new Error(ORGANIZATION_NOT_FOUND); + if (await can(userId, OrgScopes.UPDATE_ORG_BILLING, "group", groupId)) { + const group = await getOrganizationById(groupId); + if (!group) throw new Error(ORGANIZATION_NOT_FOUND); let result; - if (organization.stripeCustomerId) { - result = await updateCustomer(organization.stripeCustomerId, data); + if (group.stripeCustomerId) { + result = await updateCustomer(group.stripeCustomerId, data); } else { result = await createCustomer( - organizationId, + groupId, data, - (organizationId: string, data: organizationsUpdateInput) => - prisma.organizations.update({ + (groupId: string, data: groupsUpdateInput) => + prisma.groups.update({ where: { - id: parseInt(organizationId), + id: parseInt(groupId), }, data, }) ); } - queueWebhook(organizationId, Webhooks.UPDATE_ORGANIZATION_BILLING, data); - trackEvent( - { organizationId, type: Webhooks.UPDATE_ORGANIZATION_BILLING }, - locals - ); + queueWebhook(groupId, Webhooks.UPDATE_ORGANIZATION_BILLING, data); + trackEvent({ groupId, type: Webhooks.UPDATE_ORGANIZATION_BILLING }, locals); return result; } throw new Error(INSUFFICIENT_PERMISSION); @@ -228,21 +210,14 @@ export const updateOrganizationBillingForUser = async ( export const getOrganizationInvoicesForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, params: KeyValue ) => { - if ( - await can( - userId, - OrgScopes.READ_ORG_INVOICES, - "organization", - organizationId - ) - ) { - const organization = await getOrganizationById(organizationId); - if (!organization) throw new Error(ORGANIZATION_NOT_FOUND); - if (organization.stripeCustomerId) - return getInvoices(organization.stripeCustomerId, params); + if (await can(userId, OrgScopes.READ_ORG_INVOICES, "group", groupId)) { + const group = await getOrganizationById(groupId); + if (!group) throw new Error(ORGANIZATION_NOT_FOUND); + if (group.stripeCustomerId) + return getInvoices(group.stripeCustomerId, params); throw new Error(STRIPE_NO_CUSTOMER); } throw new Error(INSUFFICIENT_PERMISSION); @@ -250,21 +225,14 @@ export const getOrganizationInvoicesForUser = async ( export const getOrganizationInvoiceForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, invoiceId: string ) => { - if ( - await can( - userId, - OrgScopes.READ_ORG_INVOICES, - "organization", - organizationId - ) - ) { - const organization = await getOrganizationById(organizationId); - if (!organization) throw new Error(ORGANIZATION_NOT_FOUND); - if (organization.stripeCustomerId) - return getInvoice(organization.stripeCustomerId, invoiceId); + if (await can(userId, OrgScopes.READ_ORG_INVOICES, "group", groupId)) { + const group = await getOrganizationById(groupId); + if (!group) throw new Error(ORGANIZATION_NOT_FOUND); + if (group.stripeCustomerId) + return getInvoice(group.stripeCustomerId, invoiceId); throw new Error(STRIPE_NO_CUSTOMER); } throw new Error(INSUFFICIENT_PERMISSION); @@ -272,21 +240,14 @@ export const getOrganizationInvoiceForUser = async ( export const getOrganizationSourcesForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, params: KeyValue ) => { - if ( - await can( - userId, - OrgScopes.READ_ORG_SOURCES, - "organization", - organizationId - ) - ) { - const organization = await getOrganizationById(organizationId); - if (!organization) throw new Error(ORGANIZATION_NOT_FOUND); - if (organization.stripeCustomerId) - return getSources(organization.stripeCustomerId, params); + if (await can(userId, OrgScopes.READ_ORG_SOURCES, "group", groupId)) { + const group = await getOrganizationById(groupId); + if (!group) throw new Error(ORGANIZATION_NOT_FOUND); + if (group.stripeCustomerId) + return getSources(group.stripeCustomerId, params); throw new Error(STRIPE_NO_CUSTOMER); } throw new Error(INSUFFICIENT_PERMISSION); @@ -294,21 +255,14 @@ export const getOrganizationSourcesForUser = async ( export const getOrganizationSourceForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, sourceId: string ) => { - if ( - await can( - userId, - OrgScopes.READ_ORG_SOURCES, - "organization", - organizationId - ) - ) { - const organization = await getOrganizationById(organizationId); - if (!organization) throw new Error(ORGANIZATION_NOT_FOUND); - if (organization.stripeCustomerId) - return getSource(organization.stripeCustomerId, sourceId); + if (await can(userId, OrgScopes.READ_ORG_SOURCES, "group", groupId)) { + const group = await getOrganizationById(groupId); + if (!group) throw new Error(ORGANIZATION_NOT_FOUND); + if (group.stripeCustomerId) + return getSource(group.stripeCustomerId, sourceId); throw new Error(STRIPE_NO_CUSTOMER); } throw new Error(INSUFFICIENT_PERMISSION); @@ -316,21 +270,14 @@ export const getOrganizationSourceForUser = async ( export const getOrganizationSubscriptionsForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, params: KeyValue ) => { - if ( - await can( - userId, - OrgScopes.READ_ORG_SUBSCRIPTIONS, - "organization", - organizationId - ) - ) { - const organization = await getOrganizationById(organizationId); - if (!organization) throw new Error(ORGANIZATION_NOT_FOUND); - if (organization.stripeCustomerId) - return getSubscriptions(organization.stripeCustomerId, params); + if (await can(userId, OrgScopes.READ_ORG_SUBSCRIPTIONS, "group", groupId)) { + const group = await getOrganizationById(groupId); + if (!group) throw new Error(ORGANIZATION_NOT_FOUND); + if (group.stripeCustomerId) + return getSubscriptions(group.stripeCustomerId, params); throw new Error(STRIPE_NO_CUSTOMER); } throw new Error(INSUFFICIENT_PERMISSION); @@ -338,21 +285,14 @@ export const getOrganizationSubscriptionsForUser = async ( export const getOrganizationSubscriptionForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, subscriptionId: string ) => { - if ( - await can( - userId, - OrgScopes.READ_ORG_SUBSCRIPTIONS, - "organization", - organizationId - ) - ) { - const organization = await getOrganizationById(organizationId); - if (!organization) throw new Error(ORGANIZATION_NOT_FOUND); - if (organization.stripeCustomerId) - return getSubscription(organization.stripeCustomerId, subscriptionId); + if (await can(userId, OrgScopes.READ_ORG_SUBSCRIPTIONS, "group", groupId)) { + const group = await getOrganizationById(groupId); + if (!group) throw new Error(ORGANIZATION_NOT_FOUND); + if (group.stripeCustomerId) + return getSubscription(group.stripeCustomerId, subscriptionId); throw new Error(STRIPE_NO_CUSTOMER); } throw new Error(INSUFFICIENT_PERMISSION); @@ -360,34 +300,23 @@ export const getOrganizationSubscriptionForUser = async ( export const updateOrganizationSubscriptionForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, subscriptionId: string, data: KeyValue, locals?: Locals ) => { - if ( - await can( - userId, - OrgScopes.UPDATE_ORG_SUBSCRIPTIONS, - "organization", - organizationId - ) - ) { - const organization = await getOrganizationById(organizationId); - if (!organization) throw new Error(ORGANIZATION_NOT_FOUND); - if (organization.stripeCustomerId) { + if (await can(userId, OrgScopes.UPDATE_ORG_SUBSCRIPTIONS, "group", groupId)) { + const group = await getOrganizationById(groupId); + if (!group) throw new Error(ORGANIZATION_NOT_FOUND); + if (group.stripeCustomerId) { const result = await updateSubscription( - organization.stripeCustomerId, + group.stripeCustomerId, subscriptionId, data ); - queueWebhook( - organizationId, - Webhooks.UPDATE_ORGANIZATION_SUBSCRIPTION, - data - ); + queueWebhook(groupId, Webhooks.UPDATE_ORGANIZATION_SUBSCRIPTION, data); trackEvent( - { organizationId, type: Webhooks.UPDATE_ORGANIZATION_SUBSCRIPTION }, + { groupId, type: Webhooks.UPDATE_ORGANIZATION_SUBSCRIPTION }, locals ); return result; @@ -399,32 +328,18 @@ export const updateOrganizationSubscriptionForUser = async ( export const createOrganizationSubscriptionForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, params: { plan: string; [index: string]: any }, locals?: Locals ) => { - if ( - await can( - userId, - OrgScopes.CREATE_ORG_SUBSCRIPTIONS, - "organization", - organizationId - ) - ) { - const organization = await getOrganizationById(organizationId); - if (!organization) throw new Error(ORGANIZATION_NOT_FOUND); - if (organization.stripeCustomerId) { - const result = await createSubscription( - organization.stripeCustomerId, - params - ); - queueWebhook( - organizationId, - Webhooks.CREATE_ORGANIZATION_SUBSCRIPTION, - params - ); + if (await can(userId, OrgScopes.CREATE_ORG_SUBSCRIPTIONS, "group", groupId)) { + const group = await getOrganizationById(groupId); + if (!group) throw new Error(ORGANIZATION_NOT_FOUND); + if (group.stripeCustomerId) { + const result = await createSubscription(group.stripeCustomerId, params); + queueWebhook(groupId, Webhooks.CREATE_ORGANIZATION_SUBSCRIPTION, params); trackEvent( - { organizationId, type: Webhooks.CREATE_ORGANIZATION_SUBSCRIPTION }, + { groupId, type: Webhooks.CREATE_ORGANIZATION_SUBSCRIPTION }, locals ); return result; @@ -436,43 +351,27 @@ export const createOrganizationSubscriptionForUser = async ( export const getOrganizationPricingPlansForUser = async ( userId: string | ApiKeyResponse, - organizationId: string + groupId: string ) => { - if ( - await can(userId, OrgScopes.READ_ORG_PLANS, "organization", organizationId) - ) + if (await can(userId, OrgScopes.READ_ORG_PLANS, "group", groupId)) return getProductPricing(); throw new Error(INSUFFICIENT_PERMISSION); }; export const deleteOrganizationSourceForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, sourceId: string, locals?: Locals ) => { - if ( - await can( - userId, - OrgScopes.DELETE_ORG_SOURCES, - "organization", - organizationId - ) - ) { - const organization = await getOrganizationById(organizationId); - if (!organization) throw new Error(ORGANIZATION_NOT_FOUND); - if (organization.stripeCustomerId) { - const result = await deleteSource( - organization.stripeCustomerId, - sourceId - ); - queueWebhook( - organizationId, - Webhooks.DELETE_ORGANIZATION_SOURCE, - sourceId - ); + if (await can(userId, OrgScopes.DELETE_ORG_SOURCES, "group", groupId)) { + const group = await getOrganizationById(groupId); + if (!group) throw new Error(ORGANIZATION_NOT_FOUND); + if (group.stripeCustomerId) { + const result = await deleteSource(group.stripeCustomerId, sourceId); + queueWebhook(groupId, Webhooks.DELETE_ORGANIZATION_SOURCE, sourceId); trackEvent( - { organizationId, type: Webhooks.DELETE_ORGANIZATION_SOURCE }, + { groupId, type: Webhooks.DELETE_ORGANIZATION_SOURCE }, locals ); return result; @@ -484,30 +383,19 @@ export const deleteOrganizationSourceForUser = async ( export const updateOrganizationSourceForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, sourceId: string, data: any, locals?: Locals ) => { - if ( - await can( - userId, - OrgScopes.UPDATE_ORG_SOURCES, - "organization", - organizationId - ) - ) { - const organization = await getOrganizationById(organizationId); - if (!organization) throw new Error(ORGANIZATION_NOT_FOUND); - if (organization.stripeCustomerId) { - const result = await updateSource( - organization.stripeCustomerId, - sourceId, - data - ); - queueWebhook(organizationId, Webhooks.UPDATE_ORGANIZATION_SOURCE, data); + if (await can(userId, OrgScopes.UPDATE_ORG_SOURCES, "group", groupId)) { + const group = await getOrganizationById(groupId); + if (!group) throw new Error(ORGANIZATION_NOT_FOUND); + if (group.stripeCustomerId) { + const result = await updateSource(group.stripeCustomerId, sourceId, data); + queueWebhook(groupId, Webhooks.UPDATE_ORGANIZATION_SOURCE, data); trackEvent( - { organizationId, type: Webhooks.UPDATE_ORGANIZATION_SOURCE }, + { groupId, type: Webhooks.UPDATE_ORGANIZATION_SOURCE }, locals ); return result; @@ -519,25 +407,18 @@ export const updateOrganizationSourceForUser = async ( export const createOrganizationSourceForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, card: any, locals?: Locals ) => { - if ( - await can( - userId, - OrgScopes.CREATE_ORG_SOURCES, - "organization", - organizationId - ) - ) { - const organization = await getOrganizationById(organizationId); - if (!organization) throw new Error(ORGANIZATION_NOT_FOUND); - if (organization.stripeCustomerId) { - const result = await createSource(organization.stripeCustomerId, card); - queueWebhook(organizationId, Webhooks.CREATE_ORGANIZATION_SOURCE, card); + if (await can(userId, OrgScopes.CREATE_ORG_SOURCES, "group", groupId)) { + const group = await getOrganizationById(groupId); + if (!group) throw new Error(ORGANIZATION_NOT_FOUND); + if (group.stripeCustomerId) { + const result = await createSource(group.stripeCustomerId, card); + queueWebhook(groupId, Webhooks.CREATE_ORGANIZATION_SOURCE, card); trackEvent( - { organizationId, type: Webhooks.CREATE_ORGANIZATION_SOURCE }, + { groupId, type: Webhooks.CREATE_ORGANIZATION_SOURCE }, locals ); return result; @@ -549,19 +430,12 @@ export const createOrganizationSourceForUser = async ( export const getAllOrganizationDataForUser = async ( userId: string | ApiKeyResponse, - organizationId: string + groupId: string ) => { - if ( - await can( - userId, - OrgScopes.READ_ORG_TRANSACTIONS, - "organization", - organizationId - ) - ) { - const organization = await prisma.organizations.findOne({ + if (await can(userId, OrgScopes.READ_ORG_TRANSACTIONS, "group", groupId)) { + const group = await prisma.groups.findOne({ where: { - id: parseInt(organizationId), + id: parseInt(groupId), }, include: { apiKeys: true, @@ -570,18 +444,15 @@ export const getAllOrganizationDataForUser = async ( webhooks: true, }, }); - if (!organization) throw new Error(ORGANIZATION_NOT_FOUND); + if (!group) throw new Error(ORGANIZATION_NOT_FOUND); return { - ...organization, - ...(organization.stripeCustomerId + ...group, + ...(group.stripeCustomerId ? { - billing: await getCustomer(organization.stripeCustomerId), - subscriptions: await getSubscriptions( - organization.stripeCustomerId, - {} - ), - invoices: await getInvoices(organization.stripeCustomerId, {}), - sources: await getSources(organization.stripeCustomerId, {}), + billing: await getCustomer(group.stripeCustomerId), + subscriptions: await getSubscriptions(group.stripeCustomerId, {}), + invoices: await getInvoices(group.stripeCustomerId, {}), + sources: await getSources(group.stripeCustomerId, {}), } : {}), }; @@ -591,20 +462,13 @@ export const getAllOrganizationDataForUser = async ( export const getOrganizationMembershipsForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, queryParams: any ) => { - if ( - await can( - userId, - OrgScopes.READ_ORG_MEMBERSHIPS, - "organization", - organizationId - ) - ) + if (await can(userId, OrgScopes.READ_ORG_MEMBERSHIPS, "group", groupId)) return paginatedResult( await prisma.memberships.findMany({ - where: { organizationId: parseInt(organizationId) }, + where: { groupId: parseInt(groupId) }, ...queryParamsToSelect(queryParams), }), { first: queryParams.first, last: queryParams.last } @@ -614,17 +478,10 @@ export const getOrganizationMembershipsForUser = async ( export const getOrganizationMembershipForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, membershipId: string ) => { - if ( - await can( - userId, - OrgScopes.READ_ORG_MEMBERSHIPS, - "organization", - organizationId - ) - ) + if (await can(userId, OrgScopes.READ_ORG_MEMBERSHIPS, "group", groupId)) return prisma.memberships.findOne({ where: { id: parseInt(membershipId) }, include: { user: true }, @@ -634,18 +491,11 @@ export const getOrganizationMembershipForUser = async ( export const updateOrganizationMembershipForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, membershipId: string, data: membershipsUpdateInput ) => { - if ( - await can( - userId, - OrgScopes.UPDATE_ORG_MEMBERSHIPS, - "organization", - organizationId - ) - ) { + if (await can(userId, OrgScopes.UPDATE_ORG_MEMBERSHIPS, "group", groupId)) { if (data.role) { const currentMembership = await prisma.memberships.findOne({ where: { id: parseInt(membershipId) }, @@ -653,7 +503,7 @@ export const updateOrganizationMembershipForUser = async ( if (!currentMembership) throw new Error(MEMBERSHIP_NOT_FOUND); if (currentMembership.role === "OWNER" && data.role !== "OWNER") { const members = await prisma.memberships.findMany({ - where: { organizationId: parseInt(organizationId), role: "OWNER" }, + where: { groupId: parseInt(groupId), role: "OWNER" }, }); if (members.length === 1) throw new Error(CANNOT_DELETE_SOLE_MEMBER); } @@ -667,29 +517,22 @@ export const updateOrganizationMembershipForUser = async ( }; /** - * Delete an organization membership for user - * If an organization has only one member, the user, - * Delete the entire organization, not just the membership + * Delete an group membership for user + * If an group has only one member, the user, + * Delete the entire group, not just the membership */ export const deleteOrganizationMembershipForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, membershipId: string, locals: Locals ) => { - if ( - await can( - userId, - OrgScopes.DELETE_ORG_MEMBERSHIPS, - "organization", - organizationId - ) - ) { + if (await can(userId, OrgScopes.DELETE_ORG_MEMBERSHIPS, "group", groupId)) { const members = await prisma.memberships.findMany({ - where: { organizationId: parseInt(organizationId) }, + where: { groupId: parseInt(groupId) }, }); if (members.length === 1) - return deleteOrganizationForUser(userId, organizationId, locals); + return deleteOrganizationForUser(userId, groupId, locals); return prisma.memberships.delete({ where: { id: parseInt(membershipId) } }); } throw new Error(INSUFFICIENT_PERMISSION); @@ -697,28 +540,20 @@ export const deleteOrganizationMembershipForUser = async ( export const inviteMemberToOrganization = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, newMemberName: string, newMemberEmail: string, role: MembershipRole, locals: Locals ) => { - if ( - await can( - userId, - OrgScopes.CREATE_ORG_MEMBERSHIPS, - "organization", - organizationId - ) - ) { - const organization = await getOrganizationById(organizationId); - if (!organization) throw new Error(ORGANIZATION_NOT_FOUND); - if (organization.onlyAllowDomain) { + if (await can(userId, OrgScopes.CREATE_ORG_MEMBERSHIPS, "group", groupId)) { + const group = await getOrganizationById(groupId); + if (!group) throw new Error(ORGANIZATION_NOT_FOUND); + if (group.onlyAllowDomain) { const emailDomain = newMemberEmail.split("@")[1]; try { const domainDetails = await getDomainByDomainName(emailDomain); - if (domainDetails.organizationId !== parseInt(organizationId)) - throw new Error(); + if (domainDetails.groupId !== parseInt(groupId)) throw new Error(); } catch (error) { throw new Error(CANNOT_INVITE_DOMAIN); } @@ -742,7 +577,7 @@ export const inviteMemberToOrganization = async ( await prisma.memberships.findMany({ where: { userId: newUser.id, - organizationId: parseInt(organizationId), + groupId: parseInt(groupId), }, }) ).length !== 0; @@ -751,7 +586,7 @@ export const inviteMemberToOrganization = async ( await prisma.memberships.create({ data: { user: { connect: { id: newUser.id } }, - organization: { connect: { id: parseInt(organizationId) } }, + group: { connect: { id: parseInt(groupId) } }, role, }, }); @@ -760,7 +595,7 @@ export const inviteMemberToOrganization = async ( { name: newMemberName }, locals, newMemberEmail, - organizationId, + groupId, role ); createdUserId = newAccount.userId; @@ -773,7 +608,7 @@ export const inviteMemberToOrganization = async ( const userDetails = await getUserById(createdUserId); mail(newMemberEmail, Templates.INVITED_TO_TEAM, { ...userDetails, - team: organization.name, + team: group.name, inviter, }) .then(() => {}) @@ -786,20 +621,13 @@ export const inviteMemberToOrganization = async ( export const getOrganizationApiKeysForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, queryParams: any ) => { - if ( - await can( - userId, - OrgScopes.READ_ORG_API_KEYS, - "organization", - organizationId - ) - ) + if (await can(userId, OrgScopes.READ_ORG_API_KEYS, "group", groupId)) return paginatedResult( await prisma.apiKeys.findMany({ - where: { organizationId: parseInt(organizationId) }, + where: { groupId: parseInt(groupId) }, ...queryParamsToSelect(queryParams), }), { first: queryParams.first, last: queryParams.last } @@ -809,63 +637,42 @@ export const getOrganizationApiKeysForUser = async ( export const getOrganizationApiKeyForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, apiKeyId: string ) => { - if ( - await can( - userId, - OrgScopes.READ_ORG_API_KEYS, - "organization", - organizationId - ) - ) + if (await can(userId, OrgScopes.READ_ORG_API_KEYS, "group", groupId)) return prisma.apiKeys.findOne({ where: { id: parseInt(apiKeyId) } }); throw new Error(INSUFFICIENT_PERMISSION); }; export const getOrganizationApiKeyLogsForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, apiKeyId: string, query: { range?: string; from?: string; } ) => { - if ( - await can( - userId, - OrgScopes.READ_ORG_API_KEY_LOGS, - "organization", - organizationId - ) - ) + if (await can(userId, OrgScopes.READ_ORG_API_KEY_LOGS, "group", groupId)) return getApiKeyLogs(apiKeyId, query); throw new Error(INSUFFICIENT_PERMISSION); }; export const updateApiKeyForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, apiKeyId: string, data: apiKeysUpdateInput, locals: Locals ) => { - if ( - await can( - userId, - OrgScopes.UPDATE_ORG_API_KEYS, - "organization", - organizationId - ) - ) { + if (await can(userId, OrgScopes.UPDATE_ORG_API_KEYS, "group", groupId)) { const result = await prisma.apiKeys.update({ where: { id: parseInt(apiKeyId) }, data, }); - queueWebhook(organizationId, Webhooks.UPDATE_API_KEY, data); - trackEvent({ organizationId, type: Webhooks.UPDATE_API_KEY }, locals); + queueWebhook(groupId, Webhooks.UPDATE_API_KEY, data); + trackEvent({ groupId, type: Webhooks.UPDATE_API_KEY }, locals); return result; } throw new Error(INSUFFICIENT_PERMISSION); @@ -873,32 +680,25 @@ export const updateApiKeyForUser = async ( export const createApiKeyForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, apiKey: apiKeysCreateInput, locals: Locals ) => { - if ( - await can( - userId, - OrgScopes.CREATE_ORG_API_KEYS, - "organization", - organizationId - ) - ) { + if (await can(userId, OrgScopes.CREATE_ORG_API_KEYS, "group", groupId)) { apiKey.jwtApiKey = randomString({ length: 20 }); apiKey.expiresAt = apiKey.expiresAt || new Date(TOKEN_EXPIRY_API_KEY_MAX); const result = await prisma.apiKeys.create({ data: { ...apiKey, - organization: { + group: { connect: { - id: parseInt(organizationId), + id: parseInt(groupId), }, }, }, }); - queueWebhook(organizationId, Webhooks.CREATE_API_KEY, apiKey); - trackEvent({ organizationId, type: Webhooks.CREATE_API_KEY }, locals); + queueWebhook(groupId, Webhooks.CREATE_API_KEY, apiKey); + trackEvent({ groupId, type: Webhooks.CREATE_API_KEY }, locals); return result; } throw new Error(INSUFFICIENT_PERMISSION); @@ -906,23 +706,16 @@ export const createApiKeyForUser = async ( export const deleteApiKeyForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, apiKeyId: string, locals: Locals ) => { - if ( - await can( - userId, - OrgScopes.DELETE_ORG_API_KEYS, - "organization", - organizationId - ) - ) { + if (await can(userId, OrgScopes.DELETE_ORG_API_KEYS, "group", groupId)) { const result = await prisma.apiKeys.delete({ where: { id: parseInt(apiKeyId) }, }); - queueWebhook(organizationId, Webhooks.DELETE_API_KEY, apiKeyId); - trackEvent({ organizationId, type: Webhooks.DELETE_API_KEY }, locals); + queueWebhook(groupId, Webhooks.DELETE_API_KEY, apiKeyId); + trackEvent({ groupId, type: Webhooks.DELETE_API_KEY }, locals); return result; } throw new Error(INSUFFICIENT_PERMISSION); @@ -930,20 +723,13 @@ export const deleteApiKeyForUser = async ( export const getOrganizationDomainsForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, queryParams: any ) => { - if ( - await can( - userId, - OrgScopes.READ_ORG_DOMAINS, - "organization", - organizationId - ) - ) + if (await can(userId, OrgScopes.READ_ORG_DOMAINS, "group", groupId)) return paginatedResult( await prisma.domains.findMany({ - where: { organizationId: parseInt(organizationId) }, + where: { groupId: parseInt(groupId) }, ...queryParamsToSelect(queryParams), }), { first: queryParams.first, last: queryParams.last } @@ -953,42 +739,28 @@ export const getOrganizationDomainsForUser = async ( export const getOrganizationDomainForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, domainId: string ) => { - if ( - await can( - userId, - OrgScopes.READ_ORG_DOMAINS, - "organization", - organizationId - ) - ) + if (await can(userId, OrgScopes.READ_ORG_DOMAINS, "group", groupId)) return prisma.domains.findOne({ where: { id: parseInt(domainId) } }); throw new Error(INSUFFICIENT_PERMISSION); }; export const updateDomainForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, domainId: string, data: domainsUpdateInput, locals: Locals ) => { - if ( - await can( - userId, - OrgScopes.UPDATE_ORG_DOMAINS, - "organization", - organizationId - ) - ) { + if (await can(userId, OrgScopes.UPDATE_ORG_DOMAINS, "group", groupId)) { const result = await prisma.domains.update({ where: { id: parseInt(domainId) }, data, }); - queueWebhook(organizationId, Webhooks.UPDATE_DOMAIN, data); - trackEvent({ organizationId, type: Webhooks.UPDATE_DOMAIN }, locals); + queueWebhook(groupId, Webhooks.UPDATE_DOMAIN, data); + trackEvent({ groupId, type: Webhooks.UPDATE_DOMAIN }, locals); return result; } throw new Error(INSUFFICIENT_PERMISSION); @@ -996,33 +768,26 @@ export const updateDomainForUser = async ( export const createDomainForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, domain: domainsCreateInput, locals: Locals ) => { - if ( - await can( - userId, - OrgScopes.CREATE_ORG_DOMAINS, - "organization", - organizationId - ) - ) { + if (await can(userId, OrgScopes.CREATE_ORG_DOMAINS, "group", groupId)) { await checkDomainAvailability(domain.domain); const result = await prisma.domains.create({ data: { ...domain, verificationCode: await randomString({ length: 25 }), isVerified: false, - organization: { + group: { connect: { - id: parseInt(organizationId), + id: parseInt(groupId), }, }, }, }); - queueWebhook(organizationId, Webhooks.CREATE_DOMAIN, domain); - trackEvent({ organizationId, type: Webhooks.CREATE_DOMAIN }, locals); + queueWebhook(groupId, Webhooks.CREATE_DOMAIN, domain); + trackEvent({ groupId, type: Webhooks.CREATE_DOMAIN }, locals); return result; } throw new Error(INSUFFICIENT_PERMISSION); @@ -1030,23 +795,16 @@ export const createDomainForUser = async ( export const deleteDomainForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, domainId: string, locals: Locals ) => { - if ( - await can( - userId, - OrgScopes.DELETE_ORG_DOMAINS, - "organization", - organizationId - ) - ) { + if (await can(userId, OrgScopes.DELETE_ORG_DOMAINS, "group", groupId)) { const result = await prisma.domains.delete({ where: { id: parseInt(domainId) }, }); - queueWebhook(organizationId, Webhooks.DELETE_DOMAIN, domainId); - trackEvent({ organizationId, type: Webhooks.DELETE_DOMAIN }, locals); + queueWebhook(groupId, Webhooks.DELETE_DOMAIN, domainId); + trackEvent({ groupId, type: Webhooks.DELETE_DOMAIN }, locals); return result; } throw new Error(INSUFFICIENT_PERMISSION); @@ -1054,19 +812,12 @@ export const deleteDomainForUser = async ( export const verifyDomainForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, domainId: string, method: "dns" | "file", locals: Locals ) => { - if ( - await can( - userId, - OrgScopes.VERIFY_ORG_DOMAINS, - "organization", - organizationId - ) - ) { + if (await can(userId, OrgScopes.VERIFY_ORG_DOMAINS, "group", groupId)) { const domain = await prisma.domains.findOne({ where: { id: parseInt(domainId) }, }); @@ -1085,11 +836,11 @@ export const verifyDomainForUser = async ( where: { id: parseInt(domainId) }, data: { isVerified: true }, }); - queueWebhook(organizationId, Webhooks.VERIFY_DOMAIN, { + queueWebhook(groupId, Webhooks.VERIFY_DOMAIN, { domainId, method, }); - trackEvent({ organizationId, type: Webhooks.VERIFY_DOMAIN }, locals); + trackEvent({ groupId, type: Webhooks.VERIFY_DOMAIN }, locals); return result; } } catch (error) { @@ -1102,11 +853,11 @@ export const verifyDomainForUser = async ( where: { id: parseInt(domainId) }, data: { isVerified: true }, }); - queueWebhook(organizationId, Webhooks.VERIFY_DOMAIN, { + queueWebhook(groupId, Webhooks.VERIFY_DOMAIN, { domainId, method, }); - trackEvent({ organizationId, type: Webhooks.VERIFY_DOMAIN }, locals); + trackEvent({ groupId, type: Webhooks.VERIFY_DOMAIN }, locals); return result; } else { throw new Error(DOMAIN_MISSING_DNS); @@ -1119,20 +870,13 @@ export const verifyDomainForUser = async ( export const getOrganizationWebhooksForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, queryParams: any ) => { - if ( - await can( - userId, - OrgScopes.READ_ORG_WEBHOOKS, - "organization", - organizationId - ) - ) + if (await can(userId, OrgScopes.READ_ORG_WEBHOOKS, "group", groupId)) return paginatedResult( await prisma.webhooks.findMany({ - where: { organizationId: parseInt(organizationId) }, + where: { groupId: parseInt(groupId) }, ...queryParamsToSelect(queryParams), }), { first: queryParams.first, last: queryParams.last } @@ -1142,42 +886,28 @@ export const getOrganizationWebhooksForUser = async ( export const getOrganizationWebhookForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, webhookId: string ) => { - if ( - await can( - userId, - OrgScopes.READ_ORG_WEBHOOKS, - "organization", - organizationId - ) - ) + if (await can(userId, OrgScopes.READ_ORG_WEBHOOKS, "group", groupId)) return prisma.webhooks.findOne({ where: { id: parseInt(webhookId) } }); throw new Error(INSUFFICIENT_PERMISSION); }; export const updateWebhookForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, webhookId: string, data: webhooksUpdateInput, locals: Locals ) => { - if ( - await can( - userId, - OrgScopes.UPDATE_ORG_WEBHOOKS, - "organization", - organizationId - ) - ) { + if (await can(userId, OrgScopes.UPDATE_ORG_WEBHOOKS, "group", groupId)) { const result = await prisma.webhooks.update({ where: { id: parseInt(webhookId) }, data, }); - queueWebhook(organizationId, Webhooks.UPDATE_WEBHOOK, data); - trackEvent({ organizationId, type: Webhooks.UPDATE_WEBHOOK }, locals); + queueWebhook(groupId, Webhooks.UPDATE_WEBHOOK, data); + trackEvent({ groupId, type: Webhooks.UPDATE_WEBHOOK }, locals); return result; } throw new Error(INSUFFICIENT_PERMISSION); @@ -1185,24 +915,17 @@ export const updateWebhookForUser = async ( export const createWebhookForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, webhook: webhooksCreateInput, locals: Locals ) => { - if ( - await can( - userId, - OrgScopes.DELETE_ORG_WEBHOOKS, - "organization", - organizationId - ) - ) { + if (await can(userId, OrgScopes.DELETE_ORG_WEBHOOKS, "group", groupId)) { const result = await prisma.webhooks.create({ data: { ...webhook, - organization: { + group: { connect: { - id: parseInt(organizationId), + id: parseInt(groupId), }, }, }, @@ -1210,8 +933,8 @@ export const createWebhookForUser = async ( fireSingleWebhook(result, Webhooks.TEST_WEBHOOK) .then(() => {}) .catch(() => {}); - queueWebhook(organizationId, Webhooks.CREATE_WEBHOOK, webhook); - trackEvent({ organizationId, type: Webhooks.CREATE_WEBHOOK }, locals); + queueWebhook(groupId, Webhooks.CREATE_WEBHOOK, webhook); + trackEvent({ groupId, type: Webhooks.CREATE_WEBHOOK }, locals); return result; } throw new Error(INSUFFICIENT_PERMISSION); @@ -1219,23 +942,16 @@ export const createWebhookForUser = async ( export const deleteWebhookForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, webhookId: string, locals: Locals ) => { - if ( - await can( - userId, - OrgScopes.CREATE_ORG_WEBHOOKS, - "organization", - organizationId - ) - ) { + if (await can(userId, OrgScopes.CREATE_ORG_WEBHOOKS, "group", groupId)) { const result = prisma.webhooks.delete({ where: { id: parseInt(webhookId) }, }); - queueWebhook(organizationId, Webhooks.DELETE_WEBHOOK, webhookId); - trackEvent({ organizationId, type: Webhooks.DELETE_WEBHOOK }, locals); + queueWebhook(groupId, Webhooks.DELETE_WEBHOOK, webhookId); + trackEvent({ groupId, type: Webhooks.DELETE_WEBHOOK }, locals); return result; } throw new Error(INSUFFICIENT_PERMISSION); @@ -1243,17 +959,10 @@ export const deleteWebhookForUser = async ( export const applyCouponToOrganizationForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, coupon: string ) => { - if ( - await can( - userId, - OrgScopes.CREATE_ORG_TRANSACTIONS, - "organization", - organizationId - ) - ) { + if (await can(userId, OrgScopes.CREATE_ORG_TRANSACTIONS, "group", groupId)) { let amount: number | undefined = undefined; let currency: string | undefined = undefined; let description: string | undefined = undefined; @@ -1270,11 +979,11 @@ export const applyCouponToOrganizationForUser = async ( } catch (error) { throw new Error(INVALID_INPUT); } - const organization = await getOrganizationById(organizationId); - if (!organization) throw new Error(ORGANIZATION_NOT_FOUND); - if (amount && currency && organization.stripeCustomerId) { + const group = await getOrganizationById(groupId); + if (!group) throw new Error(ORGANIZATION_NOT_FOUND); + if (amount && currency && group.stripeCustomerId) { const result = await createCustomerBalanceTransaction( - organization.stripeCustomerId, + group.stripeCustomerId, { amount, currency, @@ -1291,24 +1000,14 @@ export const applyCouponToOrganizationForUser = async ( export const getOrganizationTransactionsForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, params: KeyValue ) => { - if ( - await can( - userId, - OrgScopes.READ_ORG_TRANSACTIONS, - "organization", - organizationId - ) - ) { - const organization = await getOrganizationById(organizationId); - if (!organization) throw new Error(ORGANIZATION_NOT_FOUND); - if (organization.stripeCustomerId) - return getCustomBalanceTransactions( - organization.stripeCustomerId, - params - ); + if (await can(userId, OrgScopes.READ_ORG_TRANSACTIONS, "group", groupId)) { + const group = await getOrganizationById(groupId); + if (!group) throw new Error(ORGANIZATION_NOT_FOUND); + if (group.stripeCustomerId) + return getCustomBalanceTransactions(group.stripeCustomerId, params); throw new Error(STRIPE_NO_CUSTOMER); } throw new Error(INSUFFICIENT_PERMISSION); @@ -1316,24 +1015,14 @@ export const getOrganizationTransactionsForUser = async ( export const getOrganizationTransactionForUser = async ( userId: string | ApiKeyResponse, - organizationId: string, + groupId: string, transactionId: string ) => { - if ( - await can( - userId, - OrgScopes.READ_ORG_TRANSACTIONS, - "organization", - organizationId - ) - ) { - const organization = await getOrganizationById(organizationId); - if (!organization) throw new Error(ORGANIZATION_NOT_FOUND); - if (organization.stripeCustomerId) - return getCustomBalanceTransaction( - organization.stripeCustomerId, - transactionId - ); + if (await can(userId, OrgScopes.READ_ORG_TRANSACTIONS, "group", groupId)) { + const group = await getOrganizationById(groupId); + if (!group) throw new Error(ORGANIZATION_NOT_FOUND); + if (group.stripeCustomerId) + return getCustomBalanceTransaction(group.stripeCustomerId, transactionId); throw new Error(STRIPE_NO_CUSTOMER); } throw new Error(INSUFFICIENT_PERMISSION); diff --git a/src/_staart/rest/user.ts b/src/_staart/rest/user.ts index 943644387..d3f6ad54d 100644 --- a/src/_staart/rest/user.ts +++ b/src/_staart/rest/user.ts @@ -27,7 +27,7 @@ import { } from "../services/user.service"; import { can } from "../helpers/authorization"; import { trackEvent } from "../helpers/tracking"; -import { deleteOrganizationForUser } from "./organization"; +import { deleteOrganizationForUser } from "./group"; import { EventType, UserScopes, Templates } from "../interfaces/enum"; import { Locals } from "../interfaces/general"; import { mail } from "../helpers/mail"; @@ -151,7 +151,7 @@ export const deleteUserForUser = async ( locals: Locals ) => { if (await can(tokenUserId, UserScopes.DELETE_USER, "user", updateUserId)) { - const organizationsToDelete = await prisma.organizations.findMany({ + const groupsToDelete = await prisma.groups.findMany({ select: { stripeCustomerId: true, }, @@ -161,11 +161,10 @@ export const deleteUserForUser = async ( }, }, }); - for await (const organization of organizationsToDelete) { - if (organization.stripeCustomerId) - await deleteCustomer(organization.stripeCustomerId); + for await (const group of groupsToDelete) { + if (group.stripeCustomerId) await deleteCustomer(group.stripeCustomerId); } - await prisma.organizations.deleteMany({ + await prisma.groups.deleteMany({ where: { memberships: { every: { userId: parseInt(updateUserId) }, @@ -212,7 +211,7 @@ export const getMembershipsForUser = async ( await prisma.memberships.findMany({ ...queryParamsToSelect(queryParams), where: { userId: parseInt(dataUserId) }, - include: { organization: true }, + include: { group: true }, }), { first: queryParams.first, last: queryParams.last } ); @@ -647,7 +646,7 @@ export const getMembershipDetailsForUser = async ( ) return prisma.memberships.findOne({ where: { id: parseInt(membershipId) }, - include: { user: true, organization: true }, + include: { user: true, group: true }, }); throw new Error(INSUFFICIENT_PERMISSION); }; @@ -669,17 +668,17 @@ export const deleteMembershipForUser = async ( membership ) ) { - const organizationMembers = await prisma.memberships.findMany({ - where: { organizationId: membership.organizationId }, + const groupMembers = await prisma.memberships.findMany({ + where: { groupId: membership.groupId }, }); - if (organizationMembers.length === 1) + if (groupMembers.length === 1) return deleteOrganizationForUser( tokenUserId, - String(membership.organizationId), + String(membership.groupId), locals ); if (membership.role === "OWNER") { - const currentMembers = organizationMembers.filter( + const currentMembers = groupMembers.filter( (member) => member.role === "OWNER" ); if (currentMembers.length < 2) throw new Error(CANNOT_DELETE_SOLE_OWNER); @@ -716,10 +715,10 @@ export const updateMembershipForUser = async ( if (!membership) throw new Error(MEMBERSHIP_NOT_FOUND); if (data.role !== membership.role) { if (membership.role === "OWNER") { - const organizationMembers = await prisma.memberships.findMany({ - where: { organizationId: membership.organizationId }, + const groupMembers = await prisma.memberships.findMany({ + where: { groupId: membership.groupId }, }); - const currentMembers = organizationMembers.filter( + const currentMembers = groupMembers.filter( (member) => member.role === "OWNER" ); if (currentMembers.length < 2) diff --git a/src/_staart/services/organization.service.ts b/src/_staart/services/organization.service.ts index 2b215dd49..ef2fd286a 100644 --- a/src/_staart/services/organization.service.ts +++ b/src/_staart/services/organization.service.ts @@ -26,12 +26,12 @@ import { apiKeyToken, invalidateToken } from "../helpers/jwt"; import { KeyValue } from "../interfaces/general"; import { prisma } from "../helpers/prisma"; import { - organizationsCreateInput, - organizationsUpdateInput, + groupsCreateInput, + groupsUpdateInput, apiKeysCreateInput, apiKeysUpdateInput, domainsCreateInput, - organizations, + groups, } from "@prisma/client"; import { getItemFromCache, @@ -40,14 +40,14 @@ import { } from "../helpers/cache"; /** - * Check if an organization username is available + * Check if an group username is available */ export const checkOrganizationUsernameAvailability = async ( username: string ) => { return ( ( - await prisma.organizations.findMany({ + await prisma.groups.findMany({ where: { username }, }) ).length === 0 @@ -66,33 +66,31 @@ const getBestUsernameForOrganization = async (name: string) => { }; /* - * Create a new organization for a user + * Create a new group for a user */ export const createOrganization = async ( - organization: organizationsCreateInput, + group: groupsCreateInput, ownerId: string ) => { - if (!organization.name) throw new Error(INVALID_INPUT); - organization.name = capitalizeFirstAndLastLetter(organization.name); - organization.username = await getBestUsernameForOrganization( - organization.name - ); + if (!group.name) throw new Error(INVALID_INPUT); + group.name = capitalizeFirstAndLastLetter(group.name); + group.username = await getBestUsernameForOrganization(group.name); const backgroundColor = randomColor({ luminosity: "dark", format: "hex", }).replace("#", ""); - organization.profilePicture = `https://ui-avatars.com/api/?name=${encodeURIComponent( - (organization.name || "XX").substring(0, 2).toUpperCase() + group.profilePicture = `https://ui-avatars.com/api/?name=${encodeURIComponent( + (group.name || "XX").substring(0, 2).toUpperCase() )}&background=${backgroundColor}&color=fff`; try { - const result = await prisma.organizations.create({ - data: organization, + const result = await prisma.groups.create({ + data: group, }); await prisma.memberships.create({ data: { role: "OWNER", user: { connect: { id: parseInt(ownerId) } }, - organization: { connect: { id: result.id } }, + group: { connect: { id: result.id } }, }, }); return result; @@ -103,11 +101,11 @@ export const createOrganization = async ( }; /* - * Update an organization + * Update an group */ export const updateOrganization = async ( id: string | number, - organization: organizationsUpdateInput + group: groupsUpdateInput ) => { if (typeof id === "number") id = id.toString(); const originalOrganization = await getOrganizationById(id); @@ -117,11 +115,11 @@ export const updateOrganization = async ( ); if (!originalOrganization) throw new Error(ORGANIZATION_NOT_FOUND); if ( - organization.username && + group.username && originalOrganization.username && - organization.username !== originalOrganization.username + group.username !== originalOrganization.username ) { - const currentOwners = await prisma.organizations.findMany({ + const currentOwners = await prisma.groups.findMany({ where: { username: originalOrganization.username }, }); if (currentOwners.length) { @@ -129,8 +127,8 @@ export const updateOrganization = async ( if (currentOwnerId !== parseInt(id)) throw new Error(USERNAME_EXISTS); } } - return prisma.organizations.update({ - data: organization, + return prisma.groups.update({ + data: group, where: { id: parseInt(id) }, }); }; @@ -212,12 +210,11 @@ export const getDomainByDomainName = async (domain: string) => { }; export const refreshOrganizationProfilePicture = async ( - organizationId: string | number + groupId: string | number ) => { - if (typeof organizationId === "number") - organizationId = organizationId.toString(); + if (typeof groupId === "number") groupId = groupId.toString(); const domains = await prisma.domains.findMany({ - where: { organizationId: parseInt(organizationId) }, + where: { groupId: parseInt(groupId) }, orderBy: { updatedAt: "desc" }, }); if (domains.length) { @@ -229,29 +226,29 @@ export const refreshOrganizationProfilePicture = async ( domainIcons.data.url && domainIcons.data.url !== "http://unavatar.now.sh/fallback.png" ) - return prisma.organizations.update({ + return prisma.groups.update({ data: { profilePicture: domainIcons.data.url }, - where: { id: parseInt(organizationId) }, + where: { id: parseInt(groupId) }, }); } - const organization = await prisma.organizations.findOne({ - where: { id: parseInt(organizationId) }, + const group = await prisma.groups.findOne({ + where: { id: parseInt(groupId) }, select: { name: true, username: true }, }); - if (!organization) throw new Error(ORGANIZATION_NOT_FOUND); + if (!group) throw new Error(ORGANIZATION_NOT_FOUND); const backgroundColor = randomColor({ luminosity: "dark", format: "hex", }).replace("#", ""); const profilePicture = `https://ui-avatars.com/api/?name=${encodeURIComponent( - organization.name || organization.username || "XX" + group.name || group.username || "XX" ).replace( /^([a-zA-Z0-9 _-]+)$/gi, "" )}&background=${backgroundColor}&color=fff`; - return prisma.organizations.update({ + return prisma.groups.update({ data: { profilePicture }, - where: { id: parseInt(organizationId) }, + where: { id: parseInt(groupId) }, }); }; @@ -263,7 +260,7 @@ export const createDomain = async (domain: domainsCreateInput) => { length: 32, })}`; const response = await prisma.domains.create({ data: domain }); - await refreshOrganizationProfilePicture(response.organizationId); + await refreshOrganizationProfilePicture(response.groupId); return response; }; @@ -279,41 +276,41 @@ export const checkDomainAvailability = async (username: string) => { }; /** - * Get a organization object from its ID + * Get a group object from its ID * @param id - User ID */ export const getOrganizationById = async (id: number | string) => { if (typeof id === "number") id = id.toString(); const key = `cache_getOrganizationById_${id}`; try { - return await getItemFromCache(key); + return await getItemFromCache(key); } catch (error) { - const organization = await prisma.organizations.findOne({ + const group = await prisma.groups.findOne({ where: { id: parseInt(id) }, }); - if (organization) { - await setItemInCache(key, organization); - return organization; + if (group) { + await setItemInCache(key, group); + return group; } throw new Error(ORGANIZATION_NOT_FOUND); } }; /** - * Get a organization object from its username + * Get a group object from its username * @param username - User's username */ export const getOrganizationByUsername = async (username: string) => { const key = `cache_getOrganizationByUsername_${username}`; try { - return await getItemFromCache(key); + return await getItemFromCache(key); } catch (error) { - const organization = await prisma.organizations.findOne({ + const group = await prisma.groups.findOne({ where: { username }, }); - if (organization) { - await setItemInCache(key, organization); - return organization; + if (group) { + await setItemInCache(key, group); + return group; } throw new Error(ORGANIZATION_NOT_FOUND); } diff --git a/src/_staart/services/user.service.ts b/src/_staart/services/user.service.ts index 67ba01d1c..e32fb866c 100644 --- a/src/_staart/services/user.service.ts +++ b/src/_staart/services/user.service.ts @@ -69,7 +69,7 @@ export const getBestUsernameForUser = async (name: string) => { }; /** - * Check if an organization username is available + * Check if an group username is available */ export const checkUserUsernameAvailability = async (username: string) => { return ( diff --git a/src/controllers/admin/index.ts b/src/controllers/admin/index.ts index 74b889197..edde66571 100644 --- a/src/controllers/admin/index.ts +++ b/src/controllers/admin/index.ts @@ -20,7 +20,7 @@ import { @ClassMiddleware(authHandler) export class AdminController { - @Get("organizations") + @Get("groups") async getOrganizations(req: Request, res: Response) { const userId = res.locals.token.id; if (!userId) throw new Error(MISSING_FIELD); diff --git a/src/controllers/auth/index.ts b/src/controllers/auth/index.ts index e28554a13..d121c991a 100644 --- a/src/controllers/auth/index.ts +++ b/src/controllers/auth/index.ts @@ -62,7 +62,7 @@ export class AuthController { const user = req.body; const email = req.body.email; const invitedByUser = req.body.invitedByUser; - delete user.organizationId; + delete user.groupId; delete user.email; delete user.invitedByUser; if (user.role === "ADMIN") delete user.role; @@ -71,7 +71,7 @@ export class AuthController { user, res.locals, email, - req.body.organizationId, + req.body.groupId, req.body.membershipRole ); if (invitedByUser) diff --git a/src/controllers/organizations/_id/api-keys.ts b/src/controllers/organizations/_id/api-keys.ts index 92dcc819d..761e086c0 100644 --- a/src/controllers/organizations/_id/api-keys.ts +++ b/src/controllers/organizations/_id/api-keys.ts @@ -19,7 +19,7 @@ import { Joi, joiValidate } from "@staart/validate"; import { authHandler, validator } from "../../../_staart/helpers/middleware"; import { localsToTokenOrKey, - organizationUsernameToId, + groupUsernameToId, } from "../../../_staart/helpers/utils"; import { createApiKeyForUser, @@ -28,13 +28,13 @@ import { getOrganizationApiKeyLogsForUser, getOrganizationApiKeysForUser, updateApiKeyForUser, -} from "../../../_staart/rest/organization"; +} from "../../../_staart/rest/group"; @ClassMiddleware(authHandler) export class OrganizationApiKeysController { @Get() async getUserApiKeys(req: Request, res: Response) { - const id = await organizationUsernameToId(req.params.id); + const id = await groupUsernameToId(req.params.id); joiValidate({ id: Joi.string().required() }, { id }); return getOrganizationApiKeysForUser( localsToTokenOrKey(res), @@ -57,7 +57,7 @@ export class OrganizationApiKeysController { ) ) async putUserApiKeys(req: Request, res: Response) { - const id = await organizationUsernameToId(req.params.id); + const id = await groupUsernameToId(req.params.id); joiValidate({ id: Joi.string().required() }, { id }); const added = await createApiKeyForUser( localsToTokenOrKey(res), @@ -70,7 +70,7 @@ export class OrganizationApiKeysController { @Get(":apiKeyId") async getUserApiKey(req: Request, res: Response) { - const id = await organizationUsernameToId(req.params.id); + const id = await groupUsernameToId(req.params.id); const apiKeyId = req.params.apiKeyId; joiValidate( { @@ -96,7 +96,7 @@ export class OrganizationApiKeysController { ) ) async patchUserApiKey(req: Request, res: Response) { - const id = await organizationUsernameToId(req.params.id); + const id = await groupUsernameToId(req.params.id); const apiKeyId = req.params.apiKeyId; joiValidate( { @@ -117,7 +117,7 @@ export class OrganizationApiKeysController { @Delete(":apiKeyId") async deleteUserApiKey(req: Request, res: Response) { - const id = await organizationUsernameToId(req.params.id); + const id = await groupUsernameToId(req.params.id); const apiKeyId = req.params.apiKeyId; joiValidate( { @@ -137,7 +137,7 @@ export class OrganizationApiKeysController { @Get(":apiKeyId/logs") async getUserApiKeyLogs(req: Request, res: Response) { - const id = await organizationUsernameToId(req.params.id); + const id = await groupUsernameToId(req.params.id); const apiKeyId = req.params.apiKeyId; joiValidate( { diff --git a/src/controllers/organizations/_id/billing.ts b/src/controllers/organizations/_id/billing.ts index aa76b8b49..c710144cf 100644 --- a/src/controllers/organizations/_id/billing.ts +++ b/src/controllers/organizations/_id/billing.ts @@ -10,57 +10,45 @@ import { Joi, joiValidate } from "@staart/validate"; import { authHandler } from "../../../_staart/helpers/middleware"; import { localsToTokenOrKey, - organizationUsernameToId, + groupUsernameToId, } from "../../../_staart/helpers/utils"; import { getOrganizationBillingForUser, getOrganizationPricingPlansForUser, updateOrganizationBillingForUser, -} from "../../../_staart/rest/organization"; +} from "../../../_staart/rest/group"; @ClassMiddleware(authHandler) export class OrganizationBillingController { @Get() async getBilling(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); - joiValidate( - { organizationId: Joi.string().required() }, - { organizationId } - ); - return getOrganizationBillingForUser( - localsToTokenOrKey(res), - organizationId - ); + const groupId = await groupUsernameToId(req.params.id); + joiValidate({ groupId: Joi.string().required() }, { groupId }); + return getOrganizationBillingForUser(localsToTokenOrKey(res), groupId); } @Patch() async patchBilling(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); - joiValidate( - { organizationId: Joi.string().required() }, - { organizationId } - ); + const groupId = await groupUsernameToId(req.params.id); + joiValidate({ groupId: Joi.string().required() }, { groupId }); await updateOrganizationBillingForUser( localsToTokenOrKey(res), - organizationId, + groupId, req.body, res.locals ); - return { success: true, message: "organization-billing-updated" }; + return { success: true, message: "group-billing-updated" }; } @Get("pricing") async getPlans(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); + const groupId = await groupUsernameToId(req.params.id); joiValidate( { - organizationId: Joi.string().required(), + groupId: Joi.string().required(), }, - { organizationId } - ); - return getOrganizationPricingPlansForUser( - localsToTokenOrKey(res), - organizationId + { groupId } ); + return getOrganizationPricingPlansForUser(localsToTokenOrKey(res), groupId); } } diff --git a/src/controllers/organizations/_id/domains.ts b/src/controllers/organizations/_id/domains.ts index 39bf539c5..e46d7ebbd 100644 --- a/src/controllers/organizations/_id/domains.ts +++ b/src/controllers/organizations/_id/domains.ts @@ -21,7 +21,7 @@ import { Joi, joiValidate } from "@staart/validate"; import { authHandler, validator } from "../../../_staart/helpers/middleware"; import { localsToTokenOrKey, - organizationUsernameToId, + groupUsernameToId, } from "../../../_staart/helpers/utils"; import { createDomainForUser, @@ -30,13 +30,13 @@ import { getOrganizationDomainsForUser, updateDomainForUser, verifyDomainForUser, -} from "../../../_staart/rest/organization"; +} from "../../../_staart/rest/group"; @ClassMiddleware(authHandler) export class OrganizationDomainsController { @Get() async getUserDomains(req: Request, res: Response) { - const id = await organizationUsernameToId(req.params.id); + const id = await groupUsernameToId(req.params.id); joiValidate({ id: Joi.string().required() }, { id }); return getOrganizationDomainsForUser( localsToTokenOrKey(res), @@ -55,7 +55,7 @@ export class OrganizationDomainsController { ) ) async putUserDomains(req: Request, res: Response) { - const id = await organizationUsernameToId(req.params.id); + const id = await groupUsernameToId(req.params.id); joiValidate({ id: Joi.string().required() }, { id }); const added = await createDomainForUser( localsToTokenOrKey(res), @@ -68,7 +68,7 @@ export class OrganizationDomainsController { @Get(":domainId") async getUserDomain(req: Request, res: Response) { - const id = await organizationUsernameToId(req.params.id); + const id = await groupUsernameToId(req.params.id); const domainId = req.params.domainId; joiValidate( { @@ -90,7 +90,7 @@ export class OrganizationDomainsController { ) ) async patchUserDomain(req: Request, res: Response) { - const id = await organizationUsernameToId(req.params.id); + const id = await groupUsernameToId(req.params.id); const domainId = req.params.domainId; joiValidate( { @@ -111,7 +111,7 @@ export class OrganizationDomainsController { @Delete(":domainId") async deleteUserDomain(req: Request, res: Response) { - const id = await organizationUsernameToId(req.params.id); + const id = await groupUsernameToId(req.params.id); const domainId = req.params.domainId; joiValidate( { @@ -131,7 +131,7 @@ export class OrganizationDomainsController { @Post(":domainId/verify") async verifyOrganizationDomain(req: Request, res: Response) { - const id = await organizationUsernameToId(req.params.id); + const id = await groupUsernameToId(req.params.id); const domainId = req.params.domainId; const method = req.body.method || req.query.method; joiValidate( diff --git a/src/controllers/organizations/_id/index.ts b/src/controllers/organizations/_id/index.ts index edc49598e..590120b83 100644 --- a/src/controllers/organizations/_id/index.ts +++ b/src/controllers/organizations/_id/index.ts @@ -20,7 +20,7 @@ import { Joi, joiValidate } from "@staart/validate"; import { authHandler, validator } from "../../../_staart/helpers/middleware"; import { localsToTokenOrKey, - organizationUsernameToId, + groupUsernameToId, } from "../../../_staart/helpers/utils"; import { deleteOrganizationForUser, @@ -28,19 +28,16 @@ import { getOrganizationForUser, newOrganizationForUser, updateOrganizationForUser, -} from "../../../_staart/rest/organization"; +} from "../../../_staart/rest/group"; @ClassMiddleware(authHandler) export class OrganizationController { @Get() async get(req: Request, res: Response) { - const id = await organizationUsernameToId(req.params.id); + const id = await groupUsernameToId(req.params.id); joiValidate({ id: Joi.string().required() }, { id }); - const organization = await getOrganizationForUser( - localsToTokenOrKey(res), - id - ); - return organization; + const group = await getOrganizationForUser(localsToTokenOrKey(res), id); + return group; } @Patch() @@ -59,7 +56,7 @@ export class OrganizationController { ) ) async patch(req: Request, res: Response) { - const id = await organizationUsernameToId(req.params.id); + const id = await groupUsernameToId(req.params.id); joiValidate({ id: Joi.string().required() }, { id }); const updated = await updateOrganizationForUser( localsToTokenOrKey(res), @@ -72,29 +69,16 @@ export class OrganizationController { @Delete() async delete(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); - joiValidate( - { organizationId: Joi.string().required() }, - { organizationId } - ); - await deleteOrganizationForUser( - res.locals.token.id, - organizationId, - res.locals - ); + const groupId = await groupUsernameToId(req.params.id); + joiValidate({ groupId: Joi.string().required() }, { groupId }); + await deleteOrganizationForUser(res.locals.token.id, groupId, res.locals); return respond(RESOURCE_DELETED); } @Get("data") async getData(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); - joiValidate( - { organizationId: Joi.string().required() }, - { organizationId } - ); - return getAllOrganizationDataForUser( - localsToTokenOrKey(res), - organizationId - ); + const groupId = await groupUsernameToId(req.params.id); + joiValidate({ groupId: Joi.string().required() }, { groupId }); + return getAllOrganizationDataForUser(localsToTokenOrKey(res), groupId); } } diff --git a/src/controllers/organizations/_id/invoices.ts b/src/controllers/organizations/_id/invoices.ts index aaaff8ce9..da17859a9 100644 --- a/src/controllers/organizations/_id/invoices.ts +++ b/src/controllers/organizations/_id/invoices.ts @@ -9,22 +9,19 @@ import { Joi, joiValidate } from "@staart/validate"; import { authHandler } from "../../../_staart/helpers/middleware"; import { localsToTokenOrKey, - organizationUsernameToId, + groupUsernameToId, } from "../../../_staart/helpers/utils"; import { getOrganizationInvoiceForUser, getOrganizationInvoicesForUser, -} from "../../../_staart/rest/organization"; +} from "../../../_staart/rest/group"; @ClassMiddleware(authHandler) export class OrganizationInvoicesController { @Get() async getInvoices(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); - joiValidate( - { organizationId: Joi.string().required() }, - { organizationId } - ); + const groupId = await groupUsernameToId(req.params.id); + joiValidate({ groupId: Joi.string().required() }, { groupId }); const subscriptionParams = { ...req.query }; joiValidate( { @@ -38,25 +35,25 @@ export class OrganizationInvoicesController { ); return getOrganizationInvoicesForUser( localsToTokenOrKey(res), - organizationId, + groupId, subscriptionParams ); } @Get(":invoiceId") async getInvoice(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); + const groupId = await groupUsernameToId(req.params.id); const invoiceId = req.params.invoiceId; joiValidate( { - organizationId: Joi.string().required(), + groupId: Joi.string().required(), invoiceId: Joi.string().required(), }, - { organizationId, invoiceId } + { groupId, invoiceId } ); return getOrganizationInvoiceForUser( localsToTokenOrKey(res), - organizationId, + groupId, invoiceId ); } diff --git a/src/controllers/organizations/_id/memberships.ts b/src/controllers/organizations/_id/memberships.ts index a7990f354..7b9974123 100644 --- a/src/controllers/organizations/_id/memberships.ts +++ b/src/controllers/organizations/_id/memberships.ts @@ -19,7 +19,7 @@ import { Joi, joiValidate } from "@staart/validate"; import { authHandler, validator } from "../../../_staart/helpers/middleware"; import { localsToTokenOrKey, - organizationUsernameToId, + groupUsernameToId, } from "../../../_staart/helpers/utils"; import { deleteOrganizationMembershipForUser, @@ -27,40 +27,37 @@ import { getOrganizationMembershipsForUser, inviteMemberToOrganization, updateOrganizationMembershipForUser, -} from "../../../_staart/rest/organization"; +} from "../../../_staart/rest/group"; import { MembershipRole } from "@prisma/client"; @ClassMiddleware(authHandler) export class OrganizationMembershipsController { @Get() async getMemberships(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); - joiValidate( - { organizationId: Joi.string().required() }, - { organizationId } - ); + const groupId = await groupUsernameToId(req.params.id); + joiValidate({ groupId: Joi.string().required() }, { groupId }); return getOrganizationMembershipsForUser( localsToTokenOrKey(res), - organizationId, + groupId, req.query ); } @Put() async putMemberships(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); + const groupId = await groupUsernameToId(req.params.id); const newMemberName = req.body.name; const newMemberEmail = req.body.email; const role = req.body.role; joiValidate( { - organizationId: Joi.string().required(), + groupId: Joi.string().required(), newMemberName: Joi.string().min(6).required(), newMemberEmail: Joi.string().email().required(), role: Joi.number(), }, { - organizationId, + groupId, newMemberName, newMemberEmail, role, @@ -68,7 +65,7 @@ export class OrganizationMembershipsController { ); await inviteMemberToOrganization( localsToTokenOrKey(res), - organizationId, + groupId, newMemberName, newMemberEmail, role || MembershipRole.MEMBER, @@ -79,18 +76,18 @@ export class OrganizationMembershipsController { @Get(":membershipId") async getMembership(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); + const groupId = await groupUsernameToId(req.params.id); const membershipId = req.params.membershipId; joiValidate( { - organizationId: Joi.string().required(), + groupId: Joi.string().required(), membershipId: Joi.string().required(), }, - { organizationId, membershipId } + { groupId, membershipId } ); return getOrganizationMembershipForUser( localsToTokenOrKey(res), - organizationId, + groupId, membershipId ); } @@ -105,18 +102,18 @@ export class OrganizationMembershipsController { ) ) async updateMembership(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); + const groupId = await groupUsernameToId(req.params.id); const membershipId = req.params.membershipId; joiValidate( { - organizationId: Joi.string().required(), + groupId: Joi.string().required(), membershipId: Joi.string().required(), }, - { organizationId, membershipId } + { groupId, membershipId } ); const updated = await updateOrganizationMembershipForUser( localsToTokenOrKey(res), - organizationId, + groupId, membershipId, req.body ); @@ -125,18 +122,18 @@ export class OrganizationMembershipsController { @Delete(":membershipId") async deleteMembership(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); + const groupId = await groupUsernameToId(req.params.id); const membershipId = req.params.membershipId; joiValidate( { - organizationId: Joi.string().required(), + groupId: Joi.string().required(), membershipId: Joi.string().required(), }, - { organizationId, membershipId } + { groupId, membershipId } ); await deleteOrganizationMembershipForUser( localsToTokenOrKey(res), - organizationId, + groupId, membershipId, res.locals ); diff --git a/src/controllers/organizations/_id/sources.ts b/src/controllers/organizations/_id/sources.ts index 042c8334f..30ade2d6a 100644 --- a/src/controllers/organizations/_id/sources.ts +++ b/src/controllers/organizations/_id/sources.ts @@ -18,7 +18,7 @@ import { Joi, joiValidate } from "@staart/validate"; import { authHandler } from "../../../_staart/helpers/middleware"; import { localsToTokenOrKey, - organizationUsernameToId, + groupUsernameToId, } from "../../../_staart/helpers/utils"; import { createOrganizationSourceForUser, @@ -26,17 +26,14 @@ import { getOrganizationSourceForUser, getOrganizationSourcesForUser, updateOrganizationSourceForUser, -} from "../../../_staart/rest/organization"; +} from "../../../_staart/rest/group"; @ClassMiddleware(authHandler) export class OrganizationSourcesController { @Get() async getSources(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); - joiValidate( - { organizationId: Joi.string().required() }, - { organizationId } - ); + const groupId = await groupUsernameToId(req.params.id); + joiValidate({ groupId: Joi.string().required() }, { groupId }); const subscriptionParams = { ...req.query }; joiValidate( { @@ -47,21 +44,18 @@ export class OrganizationSourcesController { ); return getOrganizationSourcesForUser( localsToTokenOrKey(res), - organizationId, + groupId, subscriptionParams ); } @Put() async putSources(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); - joiValidate( - { organizationId: Joi.string().required() }, - { organizationId } - ); + const groupId = await groupUsernameToId(req.params.id); + joiValidate({ groupId: Joi.string().required() }, { groupId }); await createOrganizationSourceForUser( localsToTokenOrKey(res), - organizationId, + groupId, req.body, res.locals ); @@ -70,18 +64,18 @@ export class OrganizationSourcesController { @Get(":sourceId") async getSource(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); + const groupId = await groupUsernameToId(req.params.id); const sourceId = req.params.sourceId; joiValidate( { - organizationId: Joi.string().required(), + groupId: Joi.string().required(), sourceId: Joi.string().required(), }, - { organizationId, sourceId } + { groupId, sourceId } ); return getOrganizationSourceForUser( localsToTokenOrKey(res), - organizationId, + groupId, sourceId ); } @@ -89,17 +83,17 @@ export class OrganizationSourcesController { @Patch(":sourceId") async patchSource(req: Request, res: Response) { const sourceId = req.params.sourceId; - const organizationId = await organizationUsernameToId(req.params.id); + const groupId = await groupUsernameToId(req.params.id); joiValidate( { - organizationId: Joi.string().required(), + groupId: Joi.string().required(), sourceId: Joi.string().required(), }, - { organizationId, sourceId } + { groupId, sourceId } ); const updated = await updateOrganizationSourceForUser( localsToTokenOrKey(res), - organizationId, + groupId, sourceId, req.body, res.locals @@ -110,17 +104,17 @@ export class OrganizationSourcesController { @Delete(":sourceId") async deleteSource(req: Request, res: Response) { const sourceId = req.params.sourceId; - const organizationId = await organizationUsernameToId(req.params.id); + const groupId = await groupUsernameToId(req.params.id); joiValidate( { - organizationId: Joi.string().required(), + groupId: Joi.string().required(), sourceId: Joi.string().required(), }, - { organizationId, sourceId } + { groupId, sourceId } ); await deleteOrganizationSourceForUser( localsToTokenOrKey(res), - organizationId, + groupId, sourceId, res.locals ); diff --git a/src/controllers/organizations/_id/subscriptions.ts b/src/controllers/organizations/_id/subscriptions.ts index e5703a477..b9dec5b28 100644 --- a/src/controllers/organizations/_id/subscriptions.ts +++ b/src/controllers/organizations/_id/subscriptions.ts @@ -12,24 +12,21 @@ import { Joi, joiValidate } from "@staart/validate"; import { authHandler } from "../../../_staart/helpers/middleware"; import { localsToTokenOrKey, - organizationUsernameToId, + groupUsernameToId, } from "../../../_staart/helpers/utils"; import { createOrganizationSubscriptionForUser, getOrganizationSubscriptionForUser, getOrganizationSubscriptionsForUser, updateOrganizationSubscriptionForUser, -} from "../../../_staart/rest/organization"; +} from "../../../_staart/rest/group"; @ClassMiddleware(authHandler) export class OrganizationSubscriptionsController { @Get() async getSubscriptions(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); - joiValidate( - { organizationId: Joi.string().required() }, - { organizationId } - ); + const groupId = await groupUsernameToId(req.params.id); + joiValidate({ groupId: Joi.string().required() }, { groupId }); const subscriptionParams = { ...req.query }; joiValidate( { @@ -43,18 +40,15 @@ export class OrganizationSubscriptionsController { ); return getOrganizationSubscriptionsForUser( localsToTokenOrKey(res), - organizationId, + groupId, subscriptionParams ); } @Put() async putSubscriptions(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); - joiValidate( - { organizationId: Joi.string().required() }, - { organizationId } - ); + const groupId = await groupUsernameToId(req.params.id); + joiValidate({ groupId: Joi.string().required() }, { groupId }); const subscriptionParams = { ...req.body }; joiValidate( { @@ -67,7 +61,7 @@ export class OrganizationSubscriptionsController { ); await createOrganizationSubscriptionForUser( localsToTokenOrKey(res), - organizationId, + groupId, subscriptionParams, res.locals ); @@ -76,33 +70,33 @@ export class OrganizationSubscriptionsController { @Get(":subscriptionId") async getSubscription(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); + const groupId = await groupUsernameToId(req.params.id); const subscriptionId = req.params.subscriptionId; joiValidate( { - organizationId: Joi.string().required(), + groupId: Joi.string().required(), subscriptionId: Joi.string().required(), }, - { organizationId, subscriptionId } + { groupId, subscriptionId } ); return getOrganizationSubscriptionForUser( localsToTokenOrKey(res), - organizationId, + groupId, subscriptionId ); } @Patch(":subscriptionId") async patchSubscription(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); + const groupId = await groupUsernameToId(req.params.id); const subscriptionId = req.params.subscriptionId; const data = req.body; joiValidate( { - organizationId: Joi.string().required(), + groupId: Joi.string().required(), subscriptionId: Joi.string().required(), }, - { organizationId, subscriptionId } + { groupId, subscriptionId } ); joiValidate( { @@ -117,7 +111,7 @@ export class OrganizationSubscriptionsController { ); await updateOrganizationSubscriptionForUser( localsToTokenOrKey(res), - organizationId, + groupId, subscriptionId, data, res.locals diff --git a/src/controllers/organizations/_id/transactions.ts b/src/controllers/organizations/_id/transactions.ts index 24543c3e1..d97b7ff29 100644 --- a/src/controllers/organizations/_id/transactions.ts +++ b/src/controllers/organizations/_id/transactions.ts @@ -10,23 +10,20 @@ import { Joi, joiValidate } from "@staart/validate"; import { authHandler } from "../../../_staart/helpers/middleware"; import { localsToTokenOrKey, - organizationUsernameToId, + groupUsernameToId, } from "../../../_staart/helpers/utils"; import { getOrganizationTransactionForUser, getOrganizationTransactionsForUser, applyCouponToOrganizationForUser, -} from "../../../_staart/rest/organization"; +} from "../../../_staart/rest/group"; @ClassMiddleware(authHandler) export class OrganizationTransactionsController { @Get() async getTransactions(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); - joiValidate( - { organizationId: Joi.string().required() }, - { organizationId } - ); + const groupId = await groupUsernameToId(req.params.id); + joiValidate({ groupId: Joi.string().required() }, { groupId }); const transactionParams = { ...req.query }; joiValidate( { @@ -37,43 +34,43 @@ export class OrganizationTransactionsController { ); return getOrganizationTransactionsForUser( localsToTokenOrKey(res), - organizationId, + groupId, transactionParams ); } @Put() async applyCoupon(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); + const groupId = await groupUsernameToId(req.params.id); const couponCode = req.body.couponCode; joiValidate( { - organizationId: Joi.string().required(), + groupId: Joi.string().required(), couponCode: Joi.string().required(), }, - { organizationId, couponCode } + { groupId, couponCode } ); return applyCouponToOrganizationForUser( localsToTokenOrKey(res), - organizationId, + groupId, couponCode ); } @Get(":transactionId") async getTransaction(req: Request, res: Response) { - const organizationId = await organizationUsernameToId(req.params.id); + const groupId = await groupUsernameToId(req.params.id); const transactionId = req.params.transactionId; joiValidate( { - organizationId: Joi.string().required(), + groupId: Joi.string().required(), transactionId: Joi.string().required(), }, - { organizationId, transactionId } + { groupId, transactionId } ); return getOrganizationTransactionForUser( localsToTokenOrKey(res), - organizationId, + groupId, transactionId ); } diff --git a/src/controllers/organizations/_id/webhooks.ts b/src/controllers/organizations/_id/webhooks.ts index c26a4b889..6f02cb455 100644 --- a/src/controllers/organizations/_id/webhooks.ts +++ b/src/controllers/organizations/_id/webhooks.ts @@ -19,7 +19,7 @@ import { Joi, joiValidate } from "@staart/validate"; import { authHandler, validator } from "../../../_staart/helpers/middleware"; import { localsToTokenOrKey, - organizationUsernameToId, + groupUsernameToId, } from "../../../_staart/helpers/utils"; import { createWebhookForUser, @@ -27,13 +27,13 @@ import { getOrganizationWebhookForUser, getOrganizationWebhooksForUser, updateWebhookForUser, -} from "../../../_staart/rest/organization"; +} from "../../../_staart/rest/group"; @ClassMiddleware(authHandler) export class OrganizationWebhooksController { @Get() async getOrganizationWebhooks(req: Request, res: Response) { - const id = await organizationUsernameToId(req.params.id); + const id = await groupUsernameToId(req.params.id); joiValidate({ id: Joi.string().required() }, { id }); return getOrganizationWebhooksForUser( localsToTokenOrKey(res), @@ -56,7 +56,7 @@ export class OrganizationWebhooksController { ) ) async putOrganizationWebhooks(req: Request, res: Response) { - const id = await organizationUsernameToId(req.params.id); + const id = await groupUsernameToId(req.params.id); joiValidate({ id: Joi.string().required() }, { id }); const added = await createWebhookForUser( localsToTokenOrKey(res), @@ -69,7 +69,7 @@ export class OrganizationWebhooksController { @Get(":webhookId") async getOrganizationWebhook(req: Request, res: Response) { - const id = await organizationUsernameToId(req.params.id); + const id = await groupUsernameToId(req.params.id); const webhookId = req.params.webhookId; joiValidate( { @@ -99,7 +99,7 @@ export class OrganizationWebhooksController { ) ) async patchOrganizationWebhook(req: Request, res: Response) { - const id = await organizationUsernameToId(req.params.id); + const id = await groupUsernameToId(req.params.id); const webhookId = req.params.webhookId; joiValidate( { @@ -120,7 +120,7 @@ export class OrganizationWebhooksController { @Delete(":webhookId") async deleteOrganizationWebhook(req: Request, res: Response) { - const id = await organizationUsernameToId(req.params.id); + const id = await groupUsernameToId(req.params.id); const webhookId = req.params.webhookId; joiValidate( { diff --git a/src/controllers/organizations/index.ts b/src/controllers/organizations/index.ts index 0a6e2a851..a119d0d19 100644 --- a/src/controllers/organizations/index.ts +++ b/src/controllers/organizations/index.ts @@ -18,7 +18,7 @@ import { } from "@staart/server"; import { Joi } from "@staart/validate"; import { authHandler, validator } from "../../_staart/helpers/middleware"; -import { newOrganizationForUser } from "../../_staart/rest/organization"; +import { newOrganizationForUser } from "../../_staart/rest/group"; @ClassMiddleware(authHandler) export class OrganizationController {