Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# These are supported funding model platforms

github: UnicisTech # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: unicis-platform-ce # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
polar: # Replace with a single Polar username
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
thanks_dev: # Replace with a single thanks.dev username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ Please star ⭐ the repo if you want us to continue developing and improving the
<img src="https://www.unicis.tech/img/frameworks/unicis-soc2.svg" alt="Unicis SOC2 Type II" height="60" style="margin-left: 10px;">
</p>

- [General Data Protection Regulation - GDPR](https://www.unicis.tech/frameworks/gdpr?mtm_campaign=GitHub%20readme)
- [Minimum Viable Secure Product - MVSP](https://www.unicis.tech/frameworks/mvsp?mtm_campaign=GitHub%20readme)
- [ISO 27001:2013 & ISO 27001:2022](https://www.unicis.tech/frameworks/iso27k?mtm_campaign=GitHub%20readme)
- [NIST Cybersecurity Framework 2.0](https://www.unicis.tech/frameworks/nist-csf2?mtm_campaign=GitHub%20readme)
- [Directive (EU) 2022/2555 NIS 2](https://www.unicis.tech/frameworks/eu-nis2?mtm_campaign=GitHub%20readme)
- [CIS Critical Security Controls Version 8.1](https://www.unicis.tech/frameworks/cis?mtm_campaign=GitHub%20readme)
- [Criteria Catalogue C5:2020](https://www.unicis.tech/frameworks/c5?mtm_campaign=GitHub%20readme)
- [SOC2 Type II - System and Organization Controls](https://www.unicis.tech/frameworks/soc?mtm_campaign=GitHub%20readme)

### Coming Next

- EU Cyber Resilience Act (CRA)
Expand All @@ -45,7 +54,7 @@ Please star ⭐ the repo if you want us to continue developing and improving the
- Cloud Controls Matrix and CAIQ v4 (CSA CCM v4)
- ISO/IEC 42001:2023 - AI management systems
- Trusted Information Security Assessment Exchange (TISAX)
- EU IA Act
- EU AI Act
- Custom ...

## 📖 Additional Resources
Expand Down
9 changes: 9 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Security Policy

## Reporting a Vulnerability

Contact: mailto:security@unicis.tech
Expires: 2027-09-09T06:30:00.000Z
Preferred-Languages: en
Policy: https://www.unicis.tech/security
OpenBugBounty: https://openbugbounty.org/bugbounty/UnicisTech/
7 changes: 1 addition & 6 deletions components/shared/shell/Brand.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@ import app from '@/lib/app';
const Brand = () => {
return (
<div className="flex pt-6 shrink-0 items-center text-xl font-bold gap-2">
<img
// className="h-7 w-auto"
src={app.logoUrl}
alt={app.name}
/>
{/* {app.name} */}
<img src={app.logoUrl} alt={app.name} />
</div>
);
};
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
"@typescript-eslint/parser": "^7.12.0",
"daisyui": "^5.0.43",
"eslint": "^8.57.1",
"eslint-config-next": "^14.2.3",
"eslint-config-next": "^16.0.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-react": "^7.34.2",
"jest": "29.7.0",
Expand Down
58 changes: 1 addition & 57 deletions pages/api/teams/[slug]/invitations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,17 @@ import { prisma } from '@/lib/prisma';
import { sendAudit } from '@/lib/retraced';
import { getSession } from '@/lib/session';
import { sendEvent } from '@/lib/svix';
import { getCurrentPlan, subscriptions } from '@/lib/subscriptions';
import {
createInvitation,
deleteInvitation,
getInvitation,
getInvitations,
isInvitationExpired,
} from 'models/invitation';
import {
addTeamMember,
getTeamMembers,
throwIfNoTeamAccess,
} from 'models/team';
import { addTeamMember, throwIfNoTeamAccess } from 'models/team';
import { throwIfNotAllowed } from 'models/user';
import type { NextApiRequest, NextApiResponse } from 'next';
import { recordMetric } from '@/lib/metrics';
import { Role } from '@prisma/client';

export default async function handler(
req: NextApiRequest,
Expand Down Expand Up @@ -62,56 +56,6 @@ const handlePOST = async (req: NextApiRequest, res: NextApiResponse) => {
throwIfNotAllowed(teamMember, 'team_invitation', 'create');

const { email, role } = req.body;
const { slug } = req.query as { slug: string };

const currentPlan = getCurrentPlan(teamMember.team.subscription);
const { maxAdmins, maxUsers } = subscriptions[currentPlan];

const teamInvitations = await getInvitations(teamMember.teamId);
const invitationsAmount = teamInvitations.length;
const adminInitationAmout = teamInvitations.filter(
({ role }) => role === Role.ADMIN || Role.OWNER
).length;

const members = await getTeamMembers(slug);

if (members.length >= maxUsers) {
return res.status(400).json({
error: {
message: 'You have reached the maximum number of members per team.',
},
});
}

if (invitationsAmount + members.length >= maxUsers) {
return res.status(400).json({
error: {
message:
'You have reached the maximum number of invitations per team, reject them to invite new members.',
},
});
}

if (role === Role.ADMIN || role === Role.OWNER) {
const adminsAmount = members.filter(
({ role }) => role === Role.ADMIN
).length;
if (adminsAmount >= maxAdmins) {
return res.status(400).json({
error: {
message: 'You have reached the maximum number of admins per team.',
},
});
}
if (adminsAmount + adminInitationAmout >= maxAdmins) {
return res.status(400).json({
error: {
message:
'You have reached the maximum number of admin invitations per team, reject them to invite new admins.',
},
});
}
}

const invitationExists = await prisma.invitation.findFirst({
where: {
Expand Down
1 change: 1 addition & 0 deletions types/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ export type ChatbotResponse = {
content: string;
role: string;
};

export type ChatbotResponseReturned = {
response: ChatbotResponse;
};
Loading