347 erro de permisionamento! - #348

Merged
GRHInvDev merged 2 commits into
mainfrom
347-ajustar-data-no-conffetti-para-puxar-a-data-correta
Mar 10, 2026
Merged

347 erro de permisionamento!#348
GRHInvDev merged 2 commits into
mainfrom
347-ajustar-data-no-conffetti-para-puxar-a-data-correta

Conversation

@rbxyz

@rbxyzrbxyz commented Mar 9, 2026

Copy link
Copy Markdown
Collaborator

Foi identificado hoje mais cedo um erro de permissão!
Um dos usuários conseguiu alterar um dos formulários sem a devida permissão!
O usuário Roger alterou o formulário de TI, inserindo acidentalmente no formulário o próprio nome!
Isso pode afetar formulários privados!

Summary by CodeRabbit

  • Bug Fixes

    • Fixed birthday detection to use UTC time for consistent behavior across timezones.
  • Improvements

    • Streamlined form editing permissions and simplified access control authorization rules.
  • Tests

    • Added comprehensive test coverage for form editing permissions and access control scenarios.

@rbxyzrbxyz linked an issue Mar 9, 2026 that may be closed by this pull request
@vercel

vercelBot commented Mar 9, 2026

Copy link
Copy Markdown

Deployment failed with the following error:

You don't have permission to create a Preview Deployment for this Vercel project: elo.

View Documentation: https://vercel.com/docs/accounts/team-members-and-roles

@rbxyzrbxyz self-assigned this Mar 9, 2026
@coderabbitai

coderabbitaiBot commented Mar 9, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The PR introduces testing infrastructure via Vitest, adds UTC-based date utilities for birthday comparisons, and simplifies form access control logic by removing private-form and sector-based permission checks while retaining creator, owner, and sudo-based authorization.

Changes

Cohort / File(s)Summary
Testing Infrastructure
package.json, vitest.config.ts
Added Vitest v2.1.0 as dev dependency with test and test:watch scripts; configured Vitest to use node environment with path aliases and test file patterns.
UTC Date Utilities
src/lib/date-utils.ts
Introduced two UTC-based date helper functions: isSameUtcMonthDay() for comparing month/day in UTC, and getUtcMonthDay() for extracting UTC month and day from dates.
Birthday Components
src/components/birthday/birthday-confetti.tsx, src/components/birthday/birthday-confetti-wrapper.tsx
Refactored birthday comparison logic to use isSameUtcMonthDay() helper instead of manual local date comparison; updated comments to reflect UTC semantics.
Access Control Refactor
src/lib/access-control.ts, src/lib/access-control-server.ts, src/server/api/routers/forms.ts
Simplified canEditForm() function by removing private-form, allowedUsers, and allowedSectors checks; now only grants edit access to creators, explicit owners, sudo users, or those with can_create_form flag. Updated form router update mutation to use consolidated canEditForm() call.
Access Control Test Coverage
src/lib/__tests__/access-control.forms-edit.test.ts
Added comprehensive unit test suite for canEditForm() covering creator/owner privileges, sudo and can_create_form flags, public/private form scenarios, and edge cases with null configs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 Hops with glee at UTC dates so bright,
Vitest runs the tests through the night,
Access controls trimmed with care,
Simpler logic fills the air!
Confetti springs from cleaner code,
Along the testing rabbit road. 🎂✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 25.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check❓ InconclusiveThe PR title '347 erro de permisionamento!' references a permission error issue but does not clearly summarize the actual changes made in the changeset.Update the title to clearly describe the main changes: consolidating permission checks in canEditForm, adding UTC date utilities, or fixing form edit authorization logic.
✅ Passed checks (1 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 347-ajustar-data-no-conffetti-para-puxar-a-data-correta

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
src/lib/date-utils.ts (1)

1-10: Add JSDoc documentation and explicit return types.

Per coding guidelines, public utility functions should have JSDoc comments with @param and @returns tags, and explicit return types.

📝 Proposed documentation and typing improvements
+/**+ * Compares two dates to check if they share the same UTC month and day.+ * `@param` a - First date to compare+ * `@param` b - Second date to compare+ * `@returns` true if both dates have the same UTC month and day+ * `@example`+ * isSameUtcMonthDay(new Date('2024-01-15'), new Date('2025-01-15')) // true+ */-export function isSameUtcMonthDay(a: Date, b: Date): boolean {+export function isSameUtcMonthDay(a: Date, b: Date): boolean {
return a.getUTCMonth() === b.getUTCMonth() && a.getUTCDate() === b.getUTCDate()
}
+/**+ * Extracts the UTC month and day from a date object.+ * `@param` date - The date to extract from+ * `@returns` Object containing UTC month (0-11) and day (1-31)+ */
export function getUtcMonthDay(date: Date): { month: number; day: number } {
return {
month: date.getUTCMonth(),
day: date.getUTCDate(),
}
}

As per coding guidelines: "Document functions and components with JSDoc comments including @param and @returns" and "Use JSDoc comments for all public functions and hooks with @param, @returns, and @example tags."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/date-utils.ts` around lines 1 - 10, Add JSDoc comments to both
exported functions isSameUtcMonthDay and getUtcMonthDay: include `@param` tags
describing the Date parameters, an `@returns` tag explaining the boolean result
for isSameUtcMonthDay and the { month:number; day:number } shape for
getUtcMonthDay, and add a brief `@example` showing usage; keep the explicit return
types (boolean and { month: number; day: number }) on the function signatures
and ensure the comments sit immediately above each function declaration.
src/lib/access-control-server.ts (1)

144-156: Consider using canEditForm to avoid logic duplication.

The permission logic here duplicates canEditForm from @/lib/access-control. This creates a maintenance risk if the permission rules change. Consider importing and using canEditForm directly.

♻️ Proposed refactor to use centralized permission check
 import "server-only";
import { redirect } from "next/navigation";
import { api } from "@/trpc/server";
import { hasAccessToAdminRoute } from "@/const/admin-routes";
+import { canEditForm } from "@/lib/access-control";
// ... existing code ...
export async function checkFormEditAccess(formId: string) {
const db_user = await api.user.me();
if (!db_user?.role_config) {
redirect("/dashboard");
}
if (db_user.role_config.isTotem) {
redirect("/dashboard");
}
const form = await api.form.getById(formId);
if (!form || !db_user.id) {
redirect("/forms");
}
- const canEdit =- form.userId === db_user.id ||- form.ownerIds?.includes(db_user.id) ||- db_user.role_config.sudo ||- db_user.role_config.can_create_form;+ const canEdit = canEditForm(+ db_user.role_config,+ db_user.id,+ formId,+ form,+ db_user.setor+ );
if (!canEdit) {
redirect("/forms");
}
return db_user;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/access-control-server.ts` around lines 144 - 156, Replace the
duplicated permission logic with the centralized canEditForm function: import
canEditForm from '@/lib/access-control' and use it to compute permission (e.g.,
const canEdit = canEditForm({ form, user: db_user })); then keep the same
redirect behavior when !form or !db_user.id and when !canEdit so behavior is
unchanged; update or remove the existing manual checks (form.userId,
form.ownerIds, db_user.role_config) in access-control-server.ts to rely on
canEditForm instead.
vitest.config.ts (1)

5-8: Consider jsdom environment for React component tests.

The environment: "node" setting works for server-side tests like access-control, but .tsx tests that render React components will require jsdom. If component tests are added later, you may need to configure per-file environments.

💡 Example for future component tests
// For per-file environment configuration, add at the top of component test files:// `@vitest-environment` jsdom// Or configure in vitest.config.ts with environmentMatchGlobs:
test: {environment: "node",environmentMatchGlobs: [["src/components/**/*.test.tsx","jsdom"],],// ...}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@vitest.config.ts` around lines 5 - 8, The test config currently sets
environment: "node" which will break React .tsx component tests; update the
Vitest test config block (the test object that contains environment) to add
per-file environment rules by adding environmentMatchGlobs mapping (key:
environmentMatchGlobs) that maps your component test glob(s) like
"src/components/**/*.test.tsx" to "jsdom", or alternatively document adding a //
`@vitest-environment` jsdom header in individual component test files so .tsx
tests run under jsdom while keeping the default environment as node.
src/lib/__tests__/access-control.forms-edit.test.ts (1)

2-2: Use the @/ alias for this internal import.

../access-control breaks the repo’s import convention and is more brittle than the configured alias.

As per coding guidelines, "Always use @/ aliases for internal imports instead of relative paths".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/__tests__/access-control.forms-edit.test.ts` at line 2, Replace the
relative import "../access-control" with the project alias import using
"@/access-control" in the test file so it follows the repo convention; locate
the import line that imports canEditForm and change it to use the "@/..." alias
(i.e., import { canEditForm } from "@/access-control") so the test uses the
configured internal path alias.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/lib/__tests__/access-control.forms-edit.test.ts`:
- Around line 111-144: The test and permission logic incorrectly treat
role_config.can_create_form as permission to edit any form; update the
canEditForm implementation so can_create_form does NOT grant edit-any
rights—only sudo or explicit ownership (userId === form.userId or form.ownerIds
includes userId) or explicit edit permissions should allow editing—and then
change the failing tests in access-control.forms-edit.test.ts to assert false
for a non-owner/non-sudo user with only can_create_form true; keep true
expectations only for sudo or actual owner scenarios and adjust references to
canEditForm, role_config.can_create_form, sudo, userId, form.userId, and
form.ownerIds accordingly.
---
Nitpick comments:
In `@src/lib/__tests__/access-control.forms-edit.test.ts`:
- Line 2: Replace the relative import "../access-control" with the project alias
import using "@/access-control" in the test file so it follows the repo
convention; locate the import line that imports canEditForm and change it to use
the "@/..." alias (i.e., import { canEditForm } from "@/access-control") so the
test uses the configured internal path alias.
In `@src/lib/access-control-server.ts`:
- Around line 144-156: Replace the duplicated permission logic with the
centralized canEditForm function: import canEditForm from '@/lib/access-control'
and use it to compute permission (e.g., const canEdit = canEditForm({ form,
user: db_user })); then keep the same redirect behavior when !form or
!db_user.id and when !canEdit so behavior is unchanged; update or remove the
existing manual checks (form.userId, form.ownerIds, db_user.role_config) in
access-control-server.ts to rely on canEditForm instead.
In `@src/lib/date-utils.ts`:
- Around line 1-10: Add JSDoc comments to both exported functions
isSameUtcMonthDay and getUtcMonthDay: include `@param` tags describing the Date
parameters, an `@returns` tag explaining the boolean result for isSameUtcMonthDay
and the { month:number; day:number } shape for getUtcMonthDay, and add a brief
`@example` showing usage; keep the explicit return types (boolean and { month:
number; day: number }) on the function signatures and ensure the comments sit
immediately above each function declaration.
In `@vitest.config.ts`:
- Around line 5-8: The test config currently sets environment: "node" which will
break React .tsx component tests; update the Vitest test config block (the test
object that contains environment) to add per-file environment rules by adding
environmentMatchGlobs mapping (key: environmentMatchGlobs) that maps your
component test glob(s) like "src/components/**/*.test.tsx" to "jsdom", or
alternatively document adding a // `@vitest-environment` jsdom header in
individual component test files so .tsx tests run under jsdom while keeping the
default environment as node.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a5d8c30e-237a-4587-87b3-be9c464ce26b

📥 Commits

Reviewing files that changed from the base of the PR and between 754cd4b and b5042b5.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • package.json
  • src/components/birthday/birthday-confetti-wrapper.tsx
  • src/components/birthday/birthday-confetti.tsx
  • src/lib/__tests__/access-control.forms-edit.test.ts
  • src/lib/access-control-server.ts
  • src/lib/access-control.ts
  • src/lib/date-utils.ts
  • src/server/api/routers/forms.ts
  • vitest.config.ts

Comment on lines +111 to +144
describe("sudo e can_create_form podem editar qualquer formulário", () => {
it("retorna true quando role_config.sudo é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, sudo: true },
otherUserId,
formId,
{
userId: creatorId,
ownerIds: [ownerId],
isPrivate: true,
allowedUsers: [],
allowedSectors: [],
},
null
);
expect(result).toBe(true);
});

it("retorna true quando role_config.can_create_form é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, can_create_form: true },
otherUserId,
formId,
{
userId: creatorId,
ownerIds: [],
isPrivate: false,
allowedUsers: [],
allowedSectors: [],
},
null
);
expect(result).toBe(true);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Don’t lock in can_create_form as edit-any-form permission.

This test suite codifies the privilege escalation the PR is trying to close. If can_create_form alone returns true here, any user with form-creation rights can still modify unrelated — including private — forms they do not own.

🔐 Suggested test update
- describe("sudo e can_create_form podem editar qualquer formulário", () => {+ describe("apenas sudo pode editar qualquer formulário", () => {
it("retorna true quando role_config.sudo é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, sudo: true },
otherUserId,
formId,
@@
);
expect(result).toBe(true);
});
- it("retorna true quando role_config.can_create_form é true", () => {+ it("retorna false quando role_config.can_create_form é true, mas o usuário não é owner/criador", () => {
const result = canEditForm(
{ ...baseRoleConfig, can_create_form: true },
otherUserId,
formId,
@@
null
);
- expect(result).toBe(true);+ expect(result).toBe(false);
});
});

As per coding guidelines, "Implement permission checks in API procedures, throwing FORBIDDEN errors when users lack sudo privileges or attempt to modify resources they don't own".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/__tests__/access-control.forms-edit.test.ts` around lines 111 - 144,
The test and permission logic incorrectly treat role_config.can_create_form as
permission to edit any form; update the canEditForm implementation so
can_create_form does NOT grant edit-any rights—only sudo or explicit ownership
(userId === form.userId or form.ownerIds includes userId) or explicit edit
permissions should allow editing—and then change the failing tests in
access-control.forms-edit.test.ts to assert false for a non-owner/non-sudo user
with only can_create_form true; keep true expectations only for sudo or actual
owner scenarios and adjust references to canEditForm,
role_config.can_create_form, sudo, userId, form.userId, and form.ownerIds
accordingly.

@GRHInvDev
GRHInvDev merged commit 36d051a into mainMar 10, 2026
7 of 9 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

INTRANET - Ajustar data no conffetti para puxar a data correta!

2 participants

@rbxyz@GRHInvDev
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

347 erro de permisionamento! - #348

Merged
GRHInvDev merged 2 commits into
mainfrom
347-ajustar-data-no-conffetti-para-puxar-a-data-correta
Mar 10, 2026
Merged

347 erro de permisionamento!#348
GRHInvDev merged 2 commits into
mainfrom
347-ajustar-data-no-conffetti-para-puxar-a-data-correta

Conversation

@rbxyz

@rbxyzrbxyz commented Mar 9, 2026

Copy link
Copy Markdown
Collaborator

Foi identificado hoje mais cedo um erro de permissão!
Um dos usuários conseguiu alterar um dos formulários sem a devida permissão!
O usuário Roger alterou o formulário de TI, inserindo acidentalmente no formulário o próprio nome!
Isso pode afetar formulários privados!

Summary by CodeRabbit

  • Bug Fixes

    • Fixed birthday detection to use UTC time for consistent behavior across timezones.
  • Improvements

    • Streamlined form editing permissions and simplified access control authorization rules.
  • Tests

    • Added comprehensive test coverage for form editing permissions and access control scenarios.

@rbxyzrbxyz linked an issue Mar 9, 2026 that may be closed by this pull request
@vercel

vercelBot commented Mar 9, 2026

Copy link
Copy Markdown

Deployment failed with the following error:

You don't have permission to create a Preview Deployment for this Vercel project: elo.

View Documentation: https://vercel.com/docs/accounts/team-members-and-roles

@rbxyzrbxyz self-assigned this Mar 9, 2026
@coderabbitai

coderabbitaiBot commented Mar 9, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The PR introduces testing infrastructure via Vitest, adds UTC-based date utilities for birthday comparisons, and simplifies form access control logic by removing private-form and sector-based permission checks while retaining creator, owner, and sudo-based authorization.

Changes

Cohort / File(s)Summary
Testing Infrastructure
package.json, vitest.config.ts
Added Vitest v2.1.0 as dev dependency with test and test:watch scripts; configured Vitest to use node environment with path aliases and test file patterns.
UTC Date Utilities
src/lib/date-utils.ts
Introduced two UTC-based date helper functions: isSameUtcMonthDay() for comparing month/day in UTC, and getUtcMonthDay() for extracting UTC month and day from dates.
Birthday Components
src/components/birthday/birthday-confetti.tsx, src/components/birthday/birthday-confetti-wrapper.tsx
Refactored birthday comparison logic to use isSameUtcMonthDay() helper instead of manual local date comparison; updated comments to reflect UTC semantics.
Access Control Refactor
src/lib/access-control.ts, src/lib/access-control-server.ts, src/server/api/routers/forms.ts
Simplified canEditForm() function by removing private-form, allowedUsers, and allowedSectors checks; now only grants edit access to creators, explicit owners, sudo users, or those with can_create_form flag. Updated form router update mutation to use consolidated canEditForm() call.
Access Control Test Coverage
src/lib/__tests__/access-control.forms-edit.test.ts
Added comprehensive unit test suite for canEditForm() covering creator/owner privileges, sudo and can_create_form flags, public/private form scenarios, and edge cases with null configs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 Hops with glee at UTC dates so bright,
Vitest runs the tests through the night,
Access controls trimmed with care,
Simpler logic fills the air!
Confetti springs from cleaner code,
Along the testing rabbit road. 🎂✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 25.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check❓ InconclusiveThe PR title '347 erro de permisionamento!' references a permission error issue but does not clearly summarize the actual changes made in the changeset.Update the title to clearly describe the main changes: consolidating permission checks in canEditForm, adding UTC date utilities, or fixing form edit authorization logic.
✅ Passed checks (1 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 347-ajustar-data-no-conffetti-para-puxar-a-data-correta

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
src/lib/date-utils.ts (1)

1-10: Add JSDoc documentation and explicit return types.

Per coding guidelines, public utility functions should have JSDoc comments with @param and @returns tags, and explicit return types.

📝 Proposed documentation and typing improvements
+/**+ * Compares two dates to check if they share the same UTC month and day.+ * `@param` a - First date to compare+ * `@param` b - Second date to compare+ * `@returns` true if both dates have the same UTC month and day+ * `@example`+ * isSameUtcMonthDay(new Date('2024-01-15'), new Date('2025-01-15')) // true+ */-export function isSameUtcMonthDay(a: Date, b: Date): boolean {+export function isSameUtcMonthDay(a: Date, b: Date): boolean {
return a.getUTCMonth() === b.getUTCMonth() && a.getUTCDate() === b.getUTCDate()
}
+/**+ * Extracts the UTC month and day from a date object.+ * `@param` date - The date to extract from+ * `@returns` Object containing UTC month (0-11) and day (1-31)+ */
export function getUtcMonthDay(date: Date): { month: number; day: number } {
return {
month: date.getUTCMonth(),
day: date.getUTCDate(),
}
}

As per coding guidelines: "Document functions and components with JSDoc comments including @param and @returns" and "Use JSDoc comments for all public functions and hooks with @param, @returns, and @example tags."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/date-utils.ts` around lines 1 - 10, Add JSDoc comments to both
exported functions isSameUtcMonthDay and getUtcMonthDay: include `@param` tags
describing the Date parameters, an `@returns` tag explaining the boolean result
for isSameUtcMonthDay and the { month:number; day:number } shape for
getUtcMonthDay, and add a brief `@example` showing usage; keep the explicit return
types (boolean and { month: number; day: number }) on the function signatures
and ensure the comments sit immediately above each function declaration.
src/lib/access-control-server.ts (1)

144-156: Consider using canEditForm to avoid logic duplication.

The permission logic here duplicates canEditForm from @/lib/access-control. This creates a maintenance risk if the permission rules change. Consider importing and using canEditForm directly.

♻️ Proposed refactor to use centralized permission check
 import "server-only";
import { redirect } from "next/navigation";
import { api } from "@/trpc/server";
import { hasAccessToAdminRoute } from "@/const/admin-routes";
+import { canEditForm } from "@/lib/access-control";
// ... existing code ...
export async function checkFormEditAccess(formId: string) {
const db_user = await api.user.me();
if (!db_user?.role_config) {
redirect("/dashboard");
}
if (db_user.role_config.isTotem) {
redirect("/dashboard");
}
const form = await api.form.getById(formId);
if (!form || !db_user.id) {
redirect("/forms");
}
- const canEdit =- form.userId === db_user.id ||- form.ownerIds?.includes(db_user.id) ||- db_user.role_config.sudo ||- db_user.role_config.can_create_form;+ const canEdit = canEditForm(+ db_user.role_config,+ db_user.id,+ formId,+ form,+ db_user.setor+ );
if (!canEdit) {
redirect("/forms");
}
return db_user;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/access-control-server.ts` around lines 144 - 156, Replace the
duplicated permission logic with the centralized canEditForm function: import
canEditForm from '@/lib/access-control' and use it to compute permission (e.g.,
const canEdit = canEditForm({ form, user: db_user })); then keep the same
redirect behavior when !form or !db_user.id and when !canEdit so behavior is
unchanged; update or remove the existing manual checks (form.userId,
form.ownerIds, db_user.role_config) in access-control-server.ts to rely on
canEditForm instead.
vitest.config.ts (1)

5-8: Consider jsdom environment for React component tests.

The environment: "node" setting works for server-side tests like access-control, but .tsx tests that render React components will require jsdom. If component tests are added later, you may need to configure per-file environments.

💡 Example for future component tests
// For per-file environment configuration, add at the top of component test files:// `@vitest-environment` jsdom// Or configure in vitest.config.ts with environmentMatchGlobs:
test: {environment: "node",environmentMatchGlobs: [["src/components/**/*.test.tsx","jsdom"],],// ...}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@vitest.config.ts` around lines 5 - 8, The test config currently sets
environment: "node" which will break React .tsx component tests; update the
Vitest test config block (the test object that contains environment) to add
per-file environment rules by adding environmentMatchGlobs mapping (key:
environmentMatchGlobs) that maps your component test glob(s) like
"src/components/**/*.test.tsx" to "jsdom", or alternatively document adding a //
`@vitest-environment` jsdom header in individual component test files so .tsx
tests run under jsdom while keeping the default environment as node.
src/lib/__tests__/access-control.forms-edit.test.ts (1)

2-2: Use the @/ alias for this internal import.

../access-control breaks the repo’s import convention and is more brittle than the configured alias.

As per coding guidelines, "Always use @/ aliases for internal imports instead of relative paths".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/__tests__/access-control.forms-edit.test.ts` at line 2, Replace the
relative import "../access-control" with the project alias import using
"@/access-control" in the test file so it follows the repo convention; locate
the import line that imports canEditForm and change it to use the "@/..." alias
(i.e., import { canEditForm } from "@/access-control") so the test uses the
configured internal path alias.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/lib/__tests__/access-control.forms-edit.test.ts`:
- Around line 111-144: The test and permission logic incorrectly treat
role_config.can_create_form as permission to edit any form; update the
canEditForm implementation so can_create_form does NOT grant edit-any
rights—only sudo or explicit ownership (userId === form.userId or form.ownerIds
includes userId) or explicit edit permissions should allow editing—and then
change the failing tests in access-control.forms-edit.test.ts to assert false
for a non-owner/non-sudo user with only can_create_form true; keep true
expectations only for sudo or actual owner scenarios and adjust references to
canEditForm, role_config.can_create_form, sudo, userId, form.userId, and
form.ownerIds accordingly.
---
Nitpick comments:
In `@src/lib/__tests__/access-control.forms-edit.test.ts`:
- Line 2: Replace the relative import "../access-control" with the project alias
import using "@/access-control" in the test file so it follows the repo
convention; locate the import line that imports canEditForm and change it to use
the "@/..." alias (i.e., import { canEditForm } from "@/access-control") so the
test uses the configured internal path alias.
In `@src/lib/access-control-server.ts`:
- Around line 144-156: Replace the duplicated permission logic with the
centralized canEditForm function: import canEditForm from '@/lib/access-control'
and use it to compute permission (e.g., const canEdit = canEditForm({ form,
user: db_user })); then keep the same redirect behavior when !form or
!db_user.id and when !canEdit so behavior is unchanged; update or remove the
existing manual checks (form.userId, form.ownerIds, db_user.role_config) in
access-control-server.ts to rely on canEditForm instead.
In `@src/lib/date-utils.ts`:
- Around line 1-10: Add JSDoc comments to both exported functions
isSameUtcMonthDay and getUtcMonthDay: include `@param` tags describing the Date
parameters, an `@returns` tag explaining the boolean result for isSameUtcMonthDay
and the { month:number; day:number } shape for getUtcMonthDay, and add a brief
`@example` showing usage; keep the explicit return types (boolean and { month:
number; day: number }) on the function signatures and ensure the comments sit
immediately above each function declaration.
In `@vitest.config.ts`:
- Around line 5-8: The test config currently sets environment: "node" which will
break React .tsx component tests; update the Vitest test config block (the test
object that contains environment) to add per-file environment rules by adding
environmentMatchGlobs mapping (key: environmentMatchGlobs) that maps your
component test glob(s) like "src/components/**/*.test.tsx" to "jsdom", or
alternatively document adding a // `@vitest-environment` jsdom header in
individual component test files so .tsx tests run under jsdom while keeping the
default environment as node.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a5d8c30e-237a-4587-87b3-be9c464ce26b

📥 Commits

Reviewing files that changed from the base of the PR and between 754cd4b and b5042b5.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • package.json
  • src/components/birthday/birthday-confetti-wrapper.tsx
  • src/components/birthday/birthday-confetti.tsx
  • src/lib/__tests__/access-control.forms-edit.test.ts
  • src/lib/access-control-server.ts
  • src/lib/access-control.ts
  • src/lib/date-utils.ts
  • src/server/api/routers/forms.ts
  • vitest.config.ts

Comment on lines +111 to +144
describe("sudo e can_create_form podem editar qualquer formulário", () => {
it("retorna true quando role_config.sudo é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, sudo: true },
otherUserId,
formId,
{
userId: creatorId,
ownerIds: [ownerId],
isPrivate: true,
allowedUsers: [],
allowedSectors: [],
},
null
);
expect(result).toBe(true);
});

it("retorna true quando role_config.can_create_form é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, can_create_form: true },
otherUserId,
formId,
{
userId: creatorId,
ownerIds: [],
isPrivate: false,
allowedUsers: [],
allowedSectors: [],
},
null
);
expect(result).toBe(true);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Don’t lock in can_create_form as edit-any-form permission.

This test suite codifies the privilege escalation the PR is trying to close. If can_create_form alone returns true here, any user with form-creation rights can still modify unrelated — including private — forms they do not own.

🔐 Suggested test update
- describe("sudo e can_create_form podem editar qualquer formulário", () => {+ describe("apenas sudo pode editar qualquer formulário", () => {
it("retorna true quando role_config.sudo é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, sudo: true },
otherUserId,
formId,
@@
);
expect(result).toBe(true);
});
- it("retorna true quando role_config.can_create_form é true", () => {+ it("retorna false quando role_config.can_create_form é true, mas o usuário não é owner/criador", () => {
const result = canEditForm(
{ ...baseRoleConfig, can_create_form: true },
otherUserId,
formId,
@@
null
);
- expect(result).toBe(true);+ expect(result).toBe(false);
});
});

As per coding guidelines, "Implement permission checks in API procedures, throwing FORBIDDEN errors when users lack sudo privileges or attempt to modify resources they don't own".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/__tests__/access-control.forms-edit.test.ts` around lines 111 - 144,
The test and permission logic incorrectly treat role_config.can_create_form as
permission to edit any form; update the canEditForm implementation so
can_create_form does NOT grant edit-any rights—only sudo or explicit ownership
(userId === form.userId or form.ownerIds includes userId) or explicit edit
permissions should allow editing—and then change the failing tests in
access-control.forms-edit.test.ts to assert false for a non-owner/non-sudo user
with only can_create_form true; keep true expectations only for sudo or actual
owner scenarios and adjust references to canEditForm,
role_config.can_create_form, sudo, userId, form.userId, and form.ownerIds
accordingly.

@GRHInvDev
GRHInvDev merged commit 36d051a into mainMar 10, 2026
7 of 9 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

INTRANET - Ajustar data no conffetti para puxar a data correta!

2 participants

@rbxyz@GRHInvDev
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

347 erro de permisionamento! - #348

Merged
GRHInvDev merged 2 commits into
mainfrom
347-ajustar-data-no-conffetti-para-puxar-a-data-correta
Mar 10, 2026
Merged

347 erro de permisionamento!#348
GRHInvDev merged 2 commits into
mainfrom
347-ajustar-data-no-conffetti-para-puxar-a-data-correta

Conversation

@rbxyz

@rbxyzrbxyz commented Mar 9, 2026

Copy link
Copy Markdown
Collaborator

Foi identificado hoje mais cedo um erro de permissão!
Um dos usuários conseguiu alterar um dos formulários sem a devida permissão!
O usuário Roger alterou o formulário de TI, inserindo acidentalmente no formulário o próprio nome!
Isso pode afetar formulários privados!

Summary by CodeRabbit

  • Bug Fixes

    • Fixed birthday detection to use UTC time for consistent behavior across timezones.
  • Improvements

    • Streamlined form editing permissions and simplified access control authorization rules.
  • Tests

    • Added comprehensive test coverage for form editing permissions and access control scenarios.

@rbxyzrbxyz linked an issue Mar 9, 2026 that may be closed by this pull request
@vercel

vercelBot commented Mar 9, 2026

Copy link
Copy Markdown

Deployment failed with the following error:

You don't have permission to create a Preview Deployment for this Vercel project: elo.

View Documentation: https://vercel.com/docs/accounts/team-members-and-roles

@rbxyzrbxyz self-assigned this Mar 9, 2026
@coderabbitai

coderabbitaiBot commented Mar 9, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The PR introduces testing infrastructure via Vitest, adds UTC-based date utilities for birthday comparisons, and simplifies form access control logic by removing private-form and sector-based permission checks while retaining creator, owner, and sudo-based authorization.

Changes

Cohort / File(s)Summary
Testing Infrastructure
package.json, vitest.config.ts
Added Vitest v2.1.0 as dev dependency with test and test:watch scripts; configured Vitest to use node environment with path aliases and test file patterns.
UTC Date Utilities
src/lib/date-utils.ts
Introduced two UTC-based date helper functions: isSameUtcMonthDay() for comparing month/day in UTC, and getUtcMonthDay() for extracting UTC month and day from dates.
Birthday Components
src/components/birthday/birthday-confetti.tsx, src/components/birthday/birthday-confetti-wrapper.tsx
Refactored birthday comparison logic to use isSameUtcMonthDay() helper instead of manual local date comparison; updated comments to reflect UTC semantics.
Access Control Refactor
src/lib/access-control.ts, src/lib/access-control-server.ts, src/server/api/routers/forms.ts
Simplified canEditForm() function by removing private-form, allowedUsers, and allowedSectors checks; now only grants edit access to creators, explicit owners, sudo users, or those with can_create_form flag. Updated form router update mutation to use consolidated canEditForm() call.
Access Control Test Coverage
src/lib/__tests__/access-control.forms-edit.test.ts
Added comprehensive unit test suite for canEditForm() covering creator/owner privileges, sudo and can_create_form flags, public/private form scenarios, and edge cases with null configs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 Hops with glee at UTC dates so bright,
Vitest runs the tests through the night,
Access controls trimmed with care,
Simpler logic fills the air!
Confetti springs from cleaner code,
Along the testing rabbit road. 🎂✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 25.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check❓ InconclusiveThe PR title '347 erro de permisionamento!' references a permission error issue but does not clearly summarize the actual changes made in the changeset.Update the title to clearly describe the main changes: consolidating permission checks in canEditForm, adding UTC date utilities, or fixing form edit authorization logic.
✅ Passed checks (1 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 347-ajustar-data-no-conffetti-para-puxar-a-data-correta

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
src/lib/date-utils.ts (1)

1-10: Add JSDoc documentation and explicit return types.

Per coding guidelines, public utility functions should have JSDoc comments with @param and @returns tags, and explicit return types.

📝 Proposed documentation and typing improvements
+/**+ * Compares two dates to check if they share the same UTC month and day.+ * `@param` a - First date to compare+ * `@param` b - Second date to compare+ * `@returns` true if both dates have the same UTC month and day+ * `@example`+ * isSameUtcMonthDay(new Date('2024-01-15'), new Date('2025-01-15')) // true+ */-export function isSameUtcMonthDay(a: Date, b: Date): boolean {+export function isSameUtcMonthDay(a: Date, b: Date): boolean {
return a.getUTCMonth() === b.getUTCMonth() && a.getUTCDate() === b.getUTCDate()
}
+/**+ * Extracts the UTC month and day from a date object.+ * `@param` date - The date to extract from+ * `@returns` Object containing UTC month (0-11) and day (1-31)+ */
export function getUtcMonthDay(date: Date): { month: number; day: number } {
return {
month: date.getUTCMonth(),
day: date.getUTCDate(),
}
}

As per coding guidelines: "Document functions and components with JSDoc comments including @param and @returns" and "Use JSDoc comments for all public functions and hooks with @param, @returns, and @example tags."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/date-utils.ts` around lines 1 - 10, Add JSDoc comments to both
exported functions isSameUtcMonthDay and getUtcMonthDay: include `@param` tags
describing the Date parameters, an `@returns` tag explaining the boolean result
for isSameUtcMonthDay and the { month:number; day:number } shape for
getUtcMonthDay, and add a brief `@example` showing usage; keep the explicit return
types (boolean and { month: number; day: number }) on the function signatures
and ensure the comments sit immediately above each function declaration.
src/lib/access-control-server.ts (1)

144-156: Consider using canEditForm to avoid logic duplication.

The permission logic here duplicates canEditForm from @/lib/access-control. This creates a maintenance risk if the permission rules change. Consider importing and using canEditForm directly.

♻️ Proposed refactor to use centralized permission check
 import "server-only";
import { redirect } from "next/navigation";
import { api } from "@/trpc/server";
import { hasAccessToAdminRoute } from "@/const/admin-routes";
+import { canEditForm } from "@/lib/access-control";
// ... existing code ...
export async function checkFormEditAccess(formId: string) {
const db_user = await api.user.me();
if (!db_user?.role_config) {
redirect("/dashboard");
}
if (db_user.role_config.isTotem) {
redirect("/dashboard");
}
const form = await api.form.getById(formId);
if (!form || !db_user.id) {
redirect("/forms");
}
- const canEdit =- form.userId === db_user.id ||- form.ownerIds?.includes(db_user.id) ||- db_user.role_config.sudo ||- db_user.role_config.can_create_form;+ const canEdit = canEditForm(+ db_user.role_config,+ db_user.id,+ formId,+ form,+ db_user.setor+ );
if (!canEdit) {
redirect("/forms");
}
return db_user;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/access-control-server.ts` around lines 144 - 156, Replace the
duplicated permission logic with the centralized canEditForm function: import
canEditForm from '@/lib/access-control' and use it to compute permission (e.g.,
const canEdit = canEditForm({ form, user: db_user })); then keep the same
redirect behavior when !form or !db_user.id and when !canEdit so behavior is
unchanged; update or remove the existing manual checks (form.userId,
form.ownerIds, db_user.role_config) in access-control-server.ts to rely on
canEditForm instead.
vitest.config.ts (1)

5-8: Consider jsdom environment for React component tests.

The environment: "node" setting works for server-side tests like access-control, but .tsx tests that render React components will require jsdom. If component tests are added later, you may need to configure per-file environments.

💡 Example for future component tests
// For per-file environment configuration, add at the top of component test files:// `@vitest-environment` jsdom// Or configure in vitest.config.ts with environmentMatchGlobs:
test: {environment: "node",environmentMatchGlobs: [["src/components/**/*.test.tsx","jsdom"],],// ...}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@vitest.config.ts` around lines 5 - 8, The test config currently sets
environment: "node" which will break React .tsx component tests; update the
Vitest test config block (the test object that contains environment) to add
per-file environment rules by adding environmentMatchGlobs mapping (key:
environmentMatchGlobs) that maps your component test glob(s) like
"src/components/**/*.test.tsx" to "jsdom", or alternatively document adding a //
`@vitest-environment` jsdom header in individual component test files so .tsx
tests run under jsdom while keeping the default environment as node.
src/lib/__tests__/access-control.forms-edit.test.ts (1)

2-2: Use the @/ alias for this internal import.

../access-control breaks the repo’s import convention and is more brittle than the configured alias.

As per coding guidelines, "Always use @/ aliases for internal imports instead of relative paths".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/__tests__/access-control.forms-edit.test.ts` at line 2, Replace the
relative import "../access-control" with the project alias import using
"@/access-control" in the test file so it follows the repo convention; locate
the import line that imports canEditForm and change it to use the "@/..." alias
(i.e., import { canEditForm } from "@/access-control") so the test uses the
configured internal path alias.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/lib/__tests__/access-control.forms-edit.test.ts`:
- Around line 111-144: The test and permission logic incorrectly treat
role_config.can_create_form as permission to edit any form; update the
canEditForm implementation so can_create_form does NOT grant edit-any
rights—only sudo or explicit ownership (userId === form.userId or form.ownerIds
includes userId) or explicit edit permissions should allow editing—and then
change the failing tests in access-control.forms-edit.test.ts to assert false
for a non-owner/non-sudo user with only can_create_form true; keep true
expectations only for sudo or actual owner scenarios and adjust references to
canEditForm, role_config.can_create_form, sudo, userId, form.userId, and
form.ownerIds accordingly.
---
Nitpick comments:
In `@src/lib/__tests__/access-control.forms-edit.test.ts`:
- Line 2: Replace the relative import "../access-control" with the project alias
import using "@/access-control" in the test file so it follows the repo
convention; locate the import line that imports canEditForm and change it to use
the "@/..." alias (i.e., import { canEditForm } from "@/access-control") so the
test uses the configured internal path alias.
In `@src/lib/access-control-server.ts`:
- Around line 144-156: Replace the duplicated permission logic with the
centralized canEditForm function: import canEditForm from '@/lib/access-control'
and use it to compute permission (e.g., const canEdit = canEditForm({ form,
user: db_user })); then keep the same redirect behavior when !form or
!db_user.id and when !canEdit so behavior is unchanged; update or remove the
existing manual checks (form.userId, form.ownerIds, db_user.role_config) in
access-control-server.ts to rely on canEditForm instead.
In `@src/lib/date-utils.ts`:
- Around line 1-10: Add JSDoc comments to both exported functions
isSameUtcMonthDay and getUtcMonthDay: include `@param` tags describing the Date
parameters, an `@returns` tag explaining the boolean result for isSameUtcMonthDay
and the { month:number; day:number } shape for getUtcMonthDay, and add a brief
`@example` showing usage; keep the explicit return types (boolean and { month:
number; day: number }) on the function signatures and ensure the comments sit
immediately above each function declaration.
In `@vitest.config.ts`:
- Around line 5-8: The test config currently sets environment: "node" which will
break React .tsx component tests; update the Vitest test config block (the test
object that contains environment) to add per-file environment rules by adding
environmentMatchGlobs mapping (key: environmentMatchGlobs) that maps your
component test glob(s) like "src/components/**/*.test.tsx" to "jsdom", or
alternatively document adding a // `@vitest-environment` jsdom header in
individual component test files so .tsx tests run under jsdom while keeping the
default environment as node.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a5d8c30e-237a-4587-87b3-be9c464ce26b

📥 Commits

Reviewing files that changed from the base of the PR and between 754cd4b and b5042b5.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • package.json
  • src/components/birthday/birthday-confetti-wrapper.tsx
  • src/components/birthday/birthday-confetti.tsx
  • src/lib/__tests__/access-control.forms-edit.test.ts
  • src/lib/access-control-server.ts
  • src/lib/access-control.ts
  • src/lib/date-utils.ts
  • src/server/api/routers/forms.ts
  • vitest.config.ts

Comment on lines +111 to +144
describe("sudo e can_create_form podem editar qualquer formulário", () => {
it("retorna true quando role_config.sudo é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, sudo: true },
otherUserId,
formId,
{
userId: creatorId,
ownerIds: [ownerId],
isPrivate: true,
allowedUsers: [],
allowedSectors: [],
},
null
);
expect(result).toBe(true);
});

it("retorna true quando role_config.can_create_form é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, can_create_form: true },
otherUserId,
formId,
{
userId: creatorId,
ownerIds: [],
isPrivate: false,
allowedUsers: [],
allowedSectors: [],
},
null
);
expect(result).toBe(true);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Don’t lock in can_create_form as edit-any-form permission.

This test suite codifies the privilege escalation the PR is trying to close. If can_create_form alone returns true here, any user with form-creation rights can still modify unrelated — including private — forms they do not own.

🔐 Suggested test update
- describe("sudo e can_create_form podem editar qualquer formulário", () => {+ describe("apenas sudo pode editar qualquer formulário", () => {
it("retorna true quando role_config.sudo é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, sudo: true },
otherUserId,
formId,
@@
);
expect(result).toBe(true);
});
- it("retorna true quando role_config.can_create_form é true", () => {+ it("retorna false quando role_config.can_create_form é true, mas o usuário não é owner/criador", () => {
const result = canEditForm(
{ ...baseRoleConfig, can_create_form: true },
otherUserId,
formId,
@@
null
);
- expect(result).toBe(true);+ expect(result).toBe(false);
});
});

As per coding guidelines, "Implement permission checks in API procedures, throwing FORBIDDEN errors when users lack sudo privileges or attempt to modify resources they don't own".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/__tests__/access-control.forms-edit.test.ts` around lines 111 - 144,
The test and permission logic incorrectly treat role_config.can_create_form as
permission to edit any form; update the canEditForm implementation so
can_create_form does NOT grant edit-any rights—only sudo or explicit ownership
(userId === form.userId or form.ownerIds includes userId) or explicit edit
permissions should allow editing—and then change the failing tests in
access-control.forms-edit.test.ts to assert false for a non-owner/non-sudo user
with only can_create_form true; keep true expectations only for sudo or actual
owner scenarios and adjust references to canEditForm,
role_config.can_create_form, sudo, userId, form.userId, and form.ownerIds
accordingly.

@GRHInvDev
GRHInvDev merged commit 36d051a into mainMar 10, 2026
7 of 9 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

INTRANET - Ajustar data no conffetti para puxar a data correta!

2 participants

@rbxyz@GRHInvDev
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

347 erro de permisionamento! - #348

Merged
GRHInvDev merged 2 commits into
mainfrom
347-ajustar-data-no-conffetti-para-puxar-a-data-correta
Mar 10, 2026
Merged

347 erro de permisionamento!#348
GRHInvDev merged 2 commits into
mainfrom
347-ajustar-data-no-conffetti-para-puxar-a-data-correta

Conversation

@rbxyz

@rbxyzrbxyz commented Mar 9, 2026

Copy link
Copy Markdown
Collaborator

Foi identificado hoje mais cedo um erro de permissão!
Um dos usuários conseguiu alterar um dos formulários sem a devida permissão!
O usuário Roger alterou o formulário de TI, inserindo acidentalmente no formulário o próprio nome!
Isso pode afetar formulários privados!

Summary by CodeRabbit

  • Bug Fixes

    • Fixed birthday detection to use UTC time for consistent behavior across timezones.
  • Improvements

    • Streamlined form editing permissions and simplified access control authorization rules.
  • Tests

    • Added comprehensive test coverage for form editing permissions and access control scenarios.

@rbxyzrbxyz linked an issue Mar 9, 2026 that may be closed by this pull request
@vercel

vercelBot commented Mar 9, 2026

Copy link
Copy Markdown

Deployment failed with the following error:

You don't have permission to create a Preview Deployment for this Vercel project: elo.

View Documentation: https://vercel.com/docs/accounts/team-members-and-roles

@rbxyzrbxyz self-assigned this Mar 9, 2026
@coderabbitai

coderabbitaiBot commented Mar 9, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The PR introduces testing infrastructure via Vitest, adds UTC-based date utilities for birthday comparisons, and simplifies form access control logic by removing private-form and sector-based permission checks while retaining creator, owner, and sudo-based authorization.

Changes

Cohort / File(s)Summary
Testing Infrastructure
package.json, vitest.config.ts
Added Vitest v2.1.0 as dev dependency with test and test:watch scripts; configured Vitest to use node environment with path aliases and test file patterns.
UTC Date Utilities
src/lib/date-utils.ts
Introduced two UTC-based date helper functions: isSameUtcMonthDay() for comparing month/day in UTC, and getUtcMonthDay() for extracting UTC month and day from dates.
Birthday Components
src/components/birthday/birthday-confetti.tsx, src/components/birthday/birthday-confetti-wrapper.tsx
Refactored birthday comparison logic to use isSameUtcMonthDay() helper instead of manual local date comparison; updated comments to reflect UTC semantics.
Access Control Refactor
src/lib/access-control.ts, src/lib/access-control-server.ts, src/server/api/routers/forms.ts
Simplified canEditForm() function by removing private-form, allowedUsers, and allowedSectors checks; now only grants edit access to creators, explicit owners, sudo users, or those with can_create_form flag. Updated form router update mutation to use consolidated canEditForm() call.
Access Control Test Coverage
src/lib/__tests__/access-control.forms-edit.test.ts
Added comprehensive unit test suite for canEditForm() covering creator/owner privileges, sudo and can_create_form flags, public/private form scenarios, and edge cases with null configs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 Hops with glee at UTC dates so bright,
Vitest runs the tests through the night,
Access controls trimmed with care,
Simpler logic fills the air!
Confetti springs from cleaner code,
Along the testing rabbit road. 🎂✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 25.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check❓ InconclusiveThe PR title '347 erro de permisionamento!' references a permission error issue but does not clearly summarize the actual changes made in the changeset.Update the title to clearly describe the main changes: consolidating permission checks in canEditForm, adding UTC date utilities, or fixing form edit authorization logic.
✅ Passed checks (1 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 347-ajustar-data-no-conffetti-para-puxar-a-data-correta

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
src/lib/date-utils.ts (1)

1-10: Add JSDoc documentation and explicit return types.

Per coding guidelines, public utility functions should have JSDoc comments with @param and @returns tags, and explicit return types.

📝 Proposed documentation and typing improvements
+/**+ * Compares two dates to check if they share the same UTC month and day.+ * `@param` a - First date to compare+ * `@param` b - Second date to compare+ * `@returns` true if both dates have the same UTC month and day+ * `@example`+ * isSameUtcMonthDay(new Date('2024-01-15'), new Date('2025-01-15')) // true+ */-export function isSameUtcMonthDay(a: Date, b: Date): boolean {+export function isSameUtcMonthDay(a: Date, b: Date): boolean {
return a.getUTCMonth() === b.getUTCMonth() && a.getUTCDate() === b.getUTCDate()
}
+/**+ * Extracts the UTC month and day from a date object.+ * `@param` date - The date to extract from+ * `@returns` Object containing UTC month (0-11) and day (1-31)+ */
export function getUtcMonthDay(date: Date): { month: number; day: number } {
return {
month: date.getUTCMonth(),
day: date.getUTCDate(),
}
}

As per coding guidelines: "Document functions and components with JSDoc comments including @param and @returns" and "Use JSDoc comments for all public functions and hooks with @param, @returns, and @example tags."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/date-utils.ts` around lines 1 - 10, Add JSDoc comments to both
exported functions isSameUtcMonthDay and getUtcMonthDay: include `@param` tags
describing the Date parameters, an `@returns` tag explaining the boolean result
for isSameUtcMonthDay and the { month:number; day:number } shape for
getUtcMonthDay, and add a brief `@example` showing usage; keep the explicit return
types (boolean and { month: number; day: number }) on the function signatures
and ensure the comments sit immediately above each function declaration.
src/lib/access-control-server.ts (1)

144-156: Consider using canEditForm to avoid logic duplication.

The permission logic here duplicates canEditForm from @/lib/access-control. This creates a maintenance risk if the permission rules change. Consider importing and using canEditForm directly.

♻️ Proposed refactor to use centralized permission check
 import "server-only";
import { redirect } from "next/navigation";
import { api } from "@/trpc/server";
import { hasAccessToAdminRoute } from "@/const/admin-routes";
+import { canEditForm } from "@/lib/access-control";
// ... existing code ...
export async function checkFormEditAccess(formId: string) {
const db_user = await api.user.me();
if (!db_user?.role_config) {
redirect("/dashboard");
}
if (db_user.role_config.isTotem) {
redirect("/dashboard");
}
const form = await api.form.getById(formId);
if (!form || !db_user.id) {
redirect("/forms");
}
- const canEdit =- form.userId === db_user.id ||- form.ownerIds?.includes(db_user.id) ||- db_user.role_config.sudo ||- db_user.role_config.can_create_form;+ const canEdit = canEditForm(+ db_user.role_config,+ db_user.id,+ formId,+ form,+ db_user.setor+ );
if (!canEdit) {
redirect("/forms");
}
return db_user;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/access-control-server.ts` around lines 144 - 156, Replace the
duplicated permission logic with the centralized canEditForm function: import
canEditForm from '@/lib/access-control' and use it to compute permission (e.g.,
const canEdit = canEditForm({ form, user: db_user })); then keep the same
redirect behavior when !form or !db_user.id and when !canEdit so behavior is
unchanged; update or remove the existing manual checks (form.userId,
form.ownerIds, db_user.role_config) in access-control-server.ts to rely on
canEditForm instead.
vitest.config.ts (1)

5-8: Consider jsdom environment for React component tests.

The environment: "node" setting works for server-side tests like access-control, but .tsx tests that render React components will require jsdom. If component tests are added later, you may need to configure per-file environments.

💡 Example for future component tests
// For per-file environment configuration, add at the top of component test files:// `@vitest-environment` jsdom// Or configure in vitest.config.ts with environmentMatchGlobs:
test: {environment: "node",environmentMatchGlobs: [["src/components/**/*.test.tsx","jsdom"],],// ...}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@vitest.config.ts` around lines 5 - 8, The test config currently sets
environment: "node" which will break React .tsx component tests; update the
Vitest test config block (the test object that contains environment) to add
per-file environment rules by adding environmentMatchGlobs mapping (key:
environmentMatchGlobs) that maps your component test glob(s) like
"src/components/**/*.test.tsx" to "jsdom", or alternatively document adding a //
`@vitest-environment` jsdom header in individual component test files so .tsx
tests run under jsdom while keeping the default environment as node.
src/lib/__tests__/access-control.forms-edit.test.ts (1)

2-2: Use the @/ alias for this internal import.

../access-control breaks the repo’s import convention and is more brittle than the configured alias.

As per coding guidelines, "Always use @/ aliases for internal imports instead of relative paths".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/__tests__/access-control.forms-edit.test.ts` at line 2, Replace the
relative import "../access-control" with the project alias import using
"@/access-control" in the test file so it follows the repo convention; locate
the import line that imports canEditForm and change it to use the "@/..." alias
(i.e., import { canEditForm } from "@/access-control") so the test uses the
configured internal path alias.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/lib/__tests__/access-control.forms-edit.test.ts`:
- Around line 111-144: The test and permission logic incorrectly treat
role_config.can_create_form as permission to edit any form; update the
canEditForm implementation so can_create_form does NOT grant edit-any
rights—only sudo or explicit ownership (userId === form.userId or form.ownerIds
includes userId) or explicit edit permissions should allow editing—and then
change the failing tests in access-control.forms-edit.test.ts to assert false
for a non-owner/non-sudo user with only can_create_form true; keep true
expectations only for sudo or actual owner scenarios and adjust references to
canEditForm, role_config.can_create_form, sudo, userId, form.userId, and
form.ownerIds accordingly.
---
Nitpick comments:
In `@src/lib/__tests__/access-control.forms-edit.test.ts`:
- Line 2: Replace the relative import "../access-control" with the project alias
import using "@/access-control" in the test file so it follows the repo
convention; locate the import line that imports canEditForm and change it to use
the "@/..." alias (i.e., import { canEditForm } from "@/access-control") so the
test uses the configured internal path alias.
In `@src/lib/access-control-server.ts`:
- Around line 144-156: Replace the duplicated permission logic with the
centralized canEditForm function: import canEditForm from '@/lib/access-control'
and use it to compute permission (e.g., const canEdit = canEditForm({ form,
user: db_user })); then keep the same redirect behavior when !form or
!db_user.id and when !canEdit so behavior is unchanged; update or remove the
existing manual checks (form.userId, form.ownerIds, db_user.role_config) in
access-control-server.ts to rely on canEditForm instead.
In `@src/lib/date-utils.ts`:
- Around line 1-10: Add JSDoc comments to both exported functions
isSameUtcMonthDay and getUtcMonthDay: include `@param` tags describing the Date
parameters, an `@returns` tag explaining the boolean result for isSameUtcMonthDay
and the { month:number; day:number } shape for getUtcMonthDay, and add a brief
`@example` showing usage; keep the explicit return types (boolean and { month:
number; day: number }) on the function signatures and ensure the comments sit
immediately above each function declaration.
In `@vitest.config.ts`:
- Around line 5-8: The test config currently sets environment: "node" which will
break React .tsx component tests; update the Vitest test config block (the test
object that contains environment) to add per-file environment rules by adding
environmentMatchGlobs mapping (key: environmentMatchGlobs) that maps your
component test glob(s) like "src/components/**/*.test.tsx" to "jsdom", or
alternatively document adding a // `@vitest-environment` jsdom header in
individual component test files so .tsx tests run under jsdom while keeping the
default environment as node.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a5d8c30e-237a-4587-87b3-be9c464ce26b

📥 Commits

Reviewing files that changed from the base of the PR and between 754cd4b and b5042b5.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • package.json
  • src/components/birthday/birthday-confetti-wrapper.tsx
  • src/components/birthday/birthday-confetti.tsx
  • src/lib/__tests__/access-control.forms-edit.test.ts
  • src/lib/access-control-server.ts
  • src/lib/access-control.ts
  • src/lib/date-utils.ts
  • src/server/api/routers/forms.ts
  • vitest.config.ts

Comment on lines +111 to +144
describe("sudo e can_create_form podem editar qualquer formulário", () => {
it("retorna true quando role_config.sudo é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, sudo: true },
otherUserId,
formId,
{
userId: creatorId,
ownerIds: [ownerId],
isPrivate: true,
allowedUsers: [],
allowedSectors: [],
},
null
);
expect(result).toBe(true);
});

it("retorna true quando role_config.can_create_form é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, can_create_form: true },
otherUserId,
formId,
{
userId: creatorId,
ownerIds: [],
isPrivate: false,
allowedUsers: [],
allowedSectors: [],
},
null
);
expect(result).toBe(true);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Don’t lock in can_create_form as edit-any-form permission.

This test suite codifies the privilege escalation the PR is trying to close. If can_create_form alone returns true here, any user with form-creation rights can still modify unrelated — including private — forms they do not own.

🔐 Suggested test update
- describe("sudo e can_create_form podem editar qualquer formulário", () => {+ describe("apenas sudo pode editar qualquer formulário", () => {
it("retorna true quando role_config.sudo é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, sudo: true },
otherUserId,
formId,
@@
);
expect(result).toBe(true);
});
- it("retorna true quando role_config.can_create_form é true", () => {+ it("retorna false quando role_config.can_create_form é true, mas o usuário não é owner/criador", () => {
const result = canEditForm(
{ ...baseRoleConfig, can_create_form: true },
otherUserId,
formId,
@@
null
);
- expect(result).toBe(true);+ expect(result).toBe(false);
});
});

As per coding guidelines, "Implement permission checks in API procedures, throwing FORBIDDEN errors when users lack sudo privileges or attempt to modify resources they don't own".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/__tests__/access-control.forms-edit.test.ts` around lines 111 - 144,
The test and permission logic incorrectly treat role_config.can_create_form as
permission to edit any form; update the canEditForm implementation so
can_create_form does NOT grant edit-any rights—only sudo or explicit ownership
(userId === form.userId or form.ownerIds includes userId) or explicit edit
permissions should allow editing—and then change the failing tests in
access-control.forms-edit.test.ts to assert false for a non-owner/non-sudo user
with only can_create_form true; keep true expectations only for sudo or actual
owner scenarios and adjust references to canEditForm,
role_config.can_create_form, sudo, userId, form.userId, and form.ownerIds
accordingly.

@GRHInvDev
GRHInvDev merged commit 36d051a into mainMar 10, 2026
7 of 9 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

INTRANET - Ajustar data no conffetti para puxar a data correta!

2 participants

@rbxyz@GRHInvDev
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

347 erro de permisionamento! - #348

Merged
GRHInvDev merged 2 commits into
mainfrom
347-ajustar-data-no-conffetti-para-puxar-a-data-correta
Mar 10, 2026
Merged

347 erro de permisionamento!#348
GRHInvDev merged 2 commits into
mainfrom
347-ajustar-data-no-conffetti-para-puxar-a-data-correta

Conversation

@rbxyz

@rbxyzrbxyz commented Mar 9, 2026

Copy link
Copy Markdown
Collaborator

Foi identificado hoje mais cedo um erro de permissão!
Um dos usuários conseguiu alterar um dos formulários sem a devida permissão!
O usuário Roger alterou o formulário de TI, inserindo acidentalmente no formulário o próprio nome!
Isso pode afetar formulários privados!

Summary by CodeRabbit

  • Bug Fixes

    • Fixed birthday detection to use UTC time for consistent behavior across timezones.
  • Improvements

    • Streamlined form editing permissions and simplified access control authorization rules.
  • Tests

    • Added comprehensive test coverage for form editing permissions and access control scenarios.

@rbxyzrbxyz linked an issue Mar 9, 2026 that may be closed by this pull request
@vercel

vercelBot commented Mar 9, 2026

Copy link
Copy Markdown

Deployment failed with the following error:

You don't have permission to create a Preview Deployment for this Vercel project: elo.

View Documentation: https://vercel.com/docs/accounts/team-members-and-roles

@rbxyzrbxyz self-assigned this Mar 9, 2026
@coderabbitai

coderabbitaiBot commented Mar 9, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The PR introduces testing infrastructure via Vitest, adds UTC-based date utilities for birthday comparisons, and simplifies form access control logic by removing private-form and sector-based permission checks while retaining creator, owner, and sudo-based authorization.

Changes

Cohort / File(s)Summary
Testing Infrastructure
package.json, vitest.config.ts
Added Vitest v2.1.0 as dev dependency with test and test:watch scripts; configured Vitest to use node environment with path aliases and test file patterns.
UTC Date Utilities
src/lib/date-utils.ts
Introduced two UTC-based date helper functions: isSameUtcMonthDay() for comparing month/day in UTC, and getUtcMonthDay() for extracting UTC month and day from dates.
Birthday Components
src/components/birthday/birthday-confetti.tsx, src/components/birthday/birthday-confetti-wrapper.tsx
Refactored birthday comparison logic to use isSameUtcMonthDay() helper instead of manual local date comparison; updated comments to reflect UTC semantics.
Access Control Refactor
src/lib/access-control.ts, src/lib/access-control-server.ts, src/server/api/routers/forms.ts
Simplified canEditForm() function by removing private-form, allowedUsers, and allowedSectors checks; now only grants edit access to creators, explicit owners, sudo users, or those with can_create_form flag. Updated form router update mutation to use consolidated canEditForm() call.
Access Control Test Coverage
src/lib/__tests__/access-control.forms-edit.test.ts
Added comprehensive unit test suite for canEditForm() covering creator/owner privileges, sudo and can_create_form flags, public/private form scenarios, and edge cases with null configs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 Hops with glee at UTC dates so bright,
Vitest runs the tests through the night,
Access controls trimmed with care,
Simpler logic fills the air!
Confetti springs from cleaner code,
Along the testing rabbit road. 🎂✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 25.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check❓ InconclusiveThe PR title '347 erro de permisionamento!' references a permission error issue but does not clearly summarize the actual changes made in the changeset.Update the title to clearly describe the main changes: consolidating permission checks in canEditForm, adding UTC date utilities, or fixing form edit authorization logic.
✅ Passed checks (1 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 347-ajustar-data-no-conffetti-para-puxar-a-data-correta

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
src/lib/date-utils.ts (1)

1-10: Add JSDoc documentation and explicit return types.

Per coding guidelines, public utility functions should have JSDoc comments with @param and @returns tags, and explicit return types.

📝 Proposed documentation and typing improvements
+/**+ * Compares two dates to check if they share the same UTC month and day.+ * `@param` a - First date to compare+ * `@param` b - Second date to compare+ * `@returns` true if both dates have the same UTC month and day+ * `@example`+ * isSameUtcMonthDay(new Date('2024-01-15'), new Date('2025-01-15')) // true+ */-export function isSameUtcMonthDay(a: Date, b: Date): boolean {+export function isSameUtcMonthDay(a: Date, b: Date): boolean {
return a.getUTCMonth() === b.getUTCMonth() && a.getUTCDate() === b.getUTCDate()
}
+/**+ * Extracts the UTC month and day from a date object.+ * `@param` date - The date to extract from+ * `@returns` Object containing UTC month (0-11) and day (1-31)+ */
export function getUtcMonthDay(date: Date): { month: number; day: number } {
return {
month: date.getUTCMonth(),
day: date.getUTCDate(),
}
}

As per coding guidelines: "Document functions and components with JSDoc comments including @param and @returns" and "Use JSDoc comments for all public functions and hooks with @param, @returns, and @example tags."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/date-utils.ts` around lines 1 - 10, Add JSDoc comments to both
exported functions isSameUtcMonthDay and getUtcMonthDay: include `@param` tags
describing the Date parameters, an `@returns` tag explaining the boolean result
for isSameUtcMonthDay and the { month:number; day:number } shape for
getUtcMonthDay, and add a brief `@example` showing usage; keep the explicit return
types (boolean and { month: number; day: number }) on the function signatures
and ensure the comments sit immediately above each function declaration.
src/lib/access-control-server.ts (1)

144-156: Consider using canEditForm to avoid logic duplication.

The permission logic here duplicates canEditForm from @/lib/access-control. This creates a maintenance risk if the permission rules change. Consider importing and using canEditForm directly.

♻️ Proposed refactor to use centralized permission check
 import "server-only";
import { redirect } from "next/navigation";
import { api } from "@/trpc/server";
import { hasAccessToAdminRoute } from "@/const/admin-routes";
+import { canEditForm } from "@/lib/access-control";
// ... existing code ...
export async function checkFormEditAccess(formId: string) {
const db_user = await api.user.me();
if (!db_user?.role_config) {
redirect("/dashboard");
}
if (db_user.role_config.isTotem) {
redirect("/dashboard");
}
const form = await api.form.getById(formId);
if (!form || !db_user.id) {
redirect("/forms");
}
- const canEdit =- form.userId === db_user.id ||- form.ownerIds?.includes(db_user.id) ||- db_user.role_config.sudo ||- db_user.role_config.can_create_form;+ const canEdit = canEditForm(+ db_user.role_config,+ db_user.id,+ formId,+ form,+ db_user.setor+ );
if (!canEdit) {
redirect("/forms");
}
return db_user;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/access-control-server.ts` around lines 144 - 156, Replace the
duplicated permission logic with the centralized canEditForm function: import
canEditForm from '@/lib/access-control' and use it to compute permission (e.g.,
const canEdit = canEditForm({ form, user: db_user })); then keep the same
redirect behavior when !form or !db_user.id and when !canEdit so behavior is
unchanged; update or remove the existing manual checks (form.userId,
form.ownerIds, db_user.role_config) in access-control-server.ts to rely on
canEditForm instead.
vitest.config.ts (1)

5-8: Consider jsdom environment for React component tests.

The environment: "node" setting works for server-side tests like access-control, but .tsx tests that render React components will require jsdom. If component tests are added later, you may need to configure per-file environments.

💡 Example for future component tests
// For per-file environment configuration, add at the top of component test files:// `@vitest-environment` jsdom// Or configure in vitest.config.ts with environmentMatchGlobs:
test: {environment: "node",environmentMatchGlobs: [["src/components/**/*.test.tsx","jsdom"],],// ...}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@vitest.config.ts` around lines 5 - 8, The test config currently sets
environment: "node" which will break React .tsx component tests; update the
Vitest test config block (the test object that contains environment) to add
per-file environment rules by adding environmentMatchGlobs mapping (key:
environmentMatchGlobs) that maps your component test glob(s) like
"src/components/**/*.test.tsx" to "jsdom", or alternatively document adding a //
`@vitest-environment` jsdom header in individual component test files so .tsx
tests run under jsdom while keeping the default environment as node.
src/lib/__tests__/access-control.forms-edit.test.ts (1)

2-2: Use the @/ alias for this internal import.

../access-control breaks the repo’s import convention and is more brittle than the configured alias.

As per coding guidelines, "Always use @/ aliases for internal imports instead of relative paths".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/__tests__/access-control.forms-edit.test.ts` at line 2, Replace the
relative import "../access-control" with the project alias import using
"@/access-control" in the test file so it follows the repo convention; locate
the import line that imports canEditForm and change it to use the "@/..." alias
(i.e., import { canEditForm } from "@/access-control") so the test uses the
configured internal path alias.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/lib/__tests__/access-control.forms-edit.test.ts`:
- Around line 111-144: The test and permission logic incorrectly treat
role_config.can_create_form as permission to edit any form; update the
canEditForm implementation so can_create_form does NOT grant edit-any
rights—only sudo or explicit ownership (userId === form.userId or form.ownerIds
includes userId) or explicit edit permissions should allow editing—and then
change the failing tests in access-control.forms-edit.test.ts to assert false
for a non-owner/non-sudo user with only can_create_form true; keep true
expectations only for sudo or actual owner scenarios and adjust references to
canEditForm, role_config.can_create_form, sudo, userId, form.userId, and
form.ownerIds accordingly.
---
Nitpick comments:
In `@src/lib/__tests__/access-control.forms-edit.test.ts`:
- Line 2: Replace the relative import "../access-control" with the project alias
import using "@/access-control" in the test file so it follows the repo
convention; locate the import line that imports canEditForm and change it to use
the "@/..." alias (i.e., import { canEditForm } from "@/access-control") so the
test uses the configured internal path alias.
In `@src/lib/access-control-server.ts`:
- Around line 144-156: Replace the duplicated permission logic with the
centralized canEditForm function: import canEditForm from '@/lib/access-control'
and use it to compute permission (e.g., const canEdit = canEditForm({ form,
user: db_user })); then keep the same redirect behavior when !form or
!db_user.id and when !canEdit so behavior is unchanged; update or remove the
existing manual checks (form.userId, form.ownerIds, db_user.role_config) in
access-control-server.ts to rely on canEditForm instead.
In `@src/lib/date-utils.ts`:
- Around line 1-10: Add JSDoc comments to both exported functions
isSameUtcMonthDay and getUtcMonthDay: include `@param` tags describing the Date
parameters, an `@returns` tag explaining the boolean result for isSameUtcMonthDay
and the { month:number; day:number } shape for getUtcMonthDay, and add a brief
`@example` showing usage; keep the explicit return types (boolean and { month:
number; day: number }) on the function signatures and ensure the comments sit
immediately above each function declaration.
In `@vitest.config.ts`:
- Around line 5-8: The test config currently sets environment: "node" which will
break React .tsx component tests; update the Vitest test config block (the test
object that contains environment) to add per-file environment rules by adding
environmentMatchGlobs mapping (key: environmentMatchGlobs) that maps your
component test glob(s) like "src/components/**/*.test.tsx" to "jsdom", or
alternatively document adding a // `@vitest-environment` jsdom header in
individual component test files so .tsx tests run under jsdom while keeping the
default environment as node.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a5d8c30e-237a-4587-87b3-be9c464ce26b

📥 Commits

Reviewing files that changed from the base of the PR and between 754cd4b and b5042b5.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • package.json
  • src/components/birthday/birthday-confetti-wrapper.tsx
  • src/components/birthday/birthday-confetti.tsx
  • src/lib/__tests__/access-control.forms-edit.test.ts
  • src/lib/access-control-server.ts
  • src/lib/access-control.ts
  • src/lib/date-utils.ts
  • src/server/api/routers/forms.ts
  • vitest.config.ts

Comment on lines +111 to +144
describe("sudo e can_create_form podem editar qualquer formulário", () => {
it("retorna true quando role_config.sudo é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, sudo: true },
otherUserId,
formId,
{
userId: creatorId,
ownerIds: [ownerId],
isPrivate: true,
allowedUsers: [],
allowedSectors: [],
},
null
);
expect(result).toBe(true);
});

it("retorna true quando role_config.can_create_form é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, can_create_form: true },
otherUserId,
formId,
{
userId: creatorId,
ownerIds: [],
isPrivate: false,
allowedUsers: [],
allowedSectors: [],
},
null
);
expect(result).toBe(true);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Don’t lock in can_create_form as edit-any-form permission.

This test suite codifies the privilege escalation the PR is trying to close. If can_create_form alone returns true here, any user with form-creation rights can still modify unrelated — including private — forms they do not own.

🔐 Suggested test update
- describe("sudo e can_create_form podem editar qualquer formulário", () => {+ describe("apenas sudo pode editar qualquer formulário", () => {
it("retorna true quando role_config.sudo é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, sudo: true },
otherUserId,
formId,
@@
);
expect(result).toBe(true);
});
- it("retorna true quando role_config.can_create_form é true", () => {+ it("retorna false quando role_config.can_create_form é true, mas o usuário não é owner/criador", () => {
const result = canEditForm(
{ ...baseRoleConfig, can_create_form: true },
otherUserId,
formId,
@@
null
);
- expect(result).toBe(true);+ expect(result).toBe(false);
});
});

As per coding guidelines, "Implement permission checks in API procedures, throwing FORBIDDEN errors when users lack sudo privileges or attempt to modify resources they don't own".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/__tests__/access-control.forms-edit.test.ts` around lines 111 - 144,
The test and permission logic incorrectly treat role_config.can_create_form as
permission to edit any form; update the canEditForm implementation so
can_create_form does NOT grant edit-any rights—only sudo or explicit ownership
(userId === form.userId or form.ownerIds includes userId) or explicit edit
permissions should allow editing—and then change the failing tests in
access-control.forms-edit.test.ts to assert false for a non-owner/non-sudo user
with only can_create_form true; keep true expectations only for sudo or actual
owner scenarios and adjust references to canEditForm,
role_config.can_create_form, sudo, userId, form.userId, and form.ownerIds
accordingly.

@GRHInvDev
GRHInvDev merged commit 36d051a into mainMar 10, 2026
7 of 9 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

INTRANET - Ajustar data no conffetti para puxar a data correta!

2 participants

@rbxyz@GRHInvDev
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

347 erro de permisionamento! - #348

Merged
GRHInvDev merged 2 commits into
mainfrom
347-ajustar-data-no-conffetti-para-puxar-a-data-correta
Mar 10, 2026
Merged

347 erro de permisionamento!#348
GRHInvDev merged 2 commits into
mainfrom
347-ajustar-data-no-conffetti-para-puxar-a-data-correta

Conversation

@rbxyz

@rbxyzrbxyz commented Mar 9, 2026

Copy link
Copy Markdown
Collaborator

Foi identificado hoje mais cedo um erro de permissão!
Um dos usuários conseguiu alterar um dos formulários sem a devida permissão!
O usuário Roger alterou o formulário de TI, inserindo acidentalmente no formulário o próprio nome!
Isso pode afetar formulários privados!

Summary by CodeRabbit

  • Bug Fixes

    • Fixed birthday detection to use UTC time for consistent behavior across timezones.
  • Improvements

    • Streamlined form editing permissions and simplified access control authorization rules.
  • Tests

    • Added comprehensive test coverage for form editing permissions and access control scenarios.

@rbxyzrbxyz linked an issue Mar 9, 2026 that may be closed by this pull request
@vercel

vercelBot commented Mar 9, 2026

Copy link
Copy Markdown

Deployment failed with the following error:

You don't have permission to create a Preview Deployment for this Vercel project: elo.

View Documentation: https://vercel.com/docs/accounts/team-members-and-roles

@rbxyzrbxyz self-assigned this Mar 9, 2026
@coderabbitai

coderabbitaiBot commented Mar 9, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The PR introduces testing infrastructure via Vitest, adds UTC-based date utilities for birthday comparisons, and simplifies form access control logic by removing private-form and sector-based permission checks while retaining creator, owner, and sudo-based authorization.

Changes

Cohort / File(s)Summary
Testing Infrastructure
package.json, vitest.config.ts
Added Vitest v2.1.0 as dev dependency with test and test:watch scripts; configured Vitest to use node environment with path aliases and test file patterns.
UTC Date Utilities
src/lib/date-utils.ts
Introduced two UTC-based date helper functions: isSameUtcMonthDay() for comparing month/day in UTC, and getUtcMonthDay() for extracting UTC month and day from dates.
Birthday Components
src/components/birthday/birthday-confetti.tsx, src/components/birthday/birthday-confetti-wrapper.tsx
Refactored birthday comparison logic to use isSameUtcMonthDay() helper instead of manual local date comparison; updated comments to reflect UTC semantics.
Access Control Refactor
src/lib/access-control.ts, src/lib/access-control-server.ts, src/server/api/routers/forms.ts
Simplified canEditForm() function by removing private-form, allowedUsers, and allowedSectors checks; now only grants edit access to creators, explicit owners, sudo users, or those with can_create_form flag. Updated form router update mutation to use consolidated canEditForm() call.
Access Control Test Coverage
src/lib/__tests__/access-control.forms-edit.test.ts
Added comprehensive unit test suite for canEditForm() covering creator/owner privileges, sudo and can_create_form flags, public/private form scenarios, and edge cases with null configs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 Hops with glee at UTC dates so bright,
Vitest runs the tests through the night,
Access controls trimmed with care,
Simpler logic fills the air!
Confetti springs from cleaner code,
Along the testing rabbit road. 🎂✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 25.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check❓ InconclusiveThe PR title '347 erro de permisionamento!' references a permission error issue but does not clearly summarize the actual changes made in the changeset.Update the title to clearly describe the main changes: consolidating permission checks in canEditForm, adding UTC date utilities, or fixing form edit authorization logic.
✅ Passed checks (1 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 347-ajustar-data-no-conffetti-para-puxar-a-data-correta

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
src/lib/date-utils.ts (1)

1-10: Add JSDoc documentation and explicit return types.

Per coding guidelines, public utility functions should have JSDoc comments with @param and @returns tags, and explicit return types.

📝 Proposed documentation and typing improvements
+/**+ * Compares two dates to check if they share the same UTC month and day.+ * `@param` a - First date to compare+ * `@param` b - Second date to compare+ * `@returns` true if both dates have the same UTC month and day+ * `@example`+ * isSameUtcMonthDay(new Date('2024-01-15'), new Date('2025-01-15')) // true+ */-export function isSameUtcMonthDay(a: Date, b: Date): boolean {+export function isSameUtcMonthDay(a: Date, b: Date): boolean {
return a.getUTCMonth() === b.getUTCMonth() && a.getUTCDate() === b.getUTCDate()
}
+/**+ * Extracts the UTC month and day from a date object.+ * `@param` date - The date to extract from+ * `@returns` Object containing UTC month (0-11) and day (1-31)+ */
export function getUtcMonthDay(date: Date): { month: number; day: number } {
return {
month: date.getUTCMonth(),
day: date.getUTCDate(),
}
}

As per coding guidelines: "Document functions and components with JSDoc comments including @param and @returns" and "Use JSDoc comments for all public functions and hooks with @param, @returns, and @example tags."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/date-utils.ts` around lines 1 - 10, Add JSDoc comments to both
exported functions isSameUtcMonthDay and getUtcMonthDay: include `@param` tags
describing the Date parameters, an `@returns` tag explaining the boolean result
for isSameUtcMonthDay and the { month:number; day:number } shape for
getUtcMonthDay, and add a brief `@example` showing usage; keep the explicit return
types (boolean and { month: number; day: number }) on the function signatures
and ensure the comments sit immediately above each function declaration.
src/lib/access-control-server.ts (1)

144-156: Consider using canEditForm to avoid logic duplication.

The permission logic here duplicates canEditForm from @/lib/access-control. This creates a maintenance risk if the permission rules change. Consider importing and using canEditForm directly.

♻️ Proposed refactor to use centralized permission check
 import "server-only";
import { redirect } from "next/navigation";
import { api } from "@/trpc/server";
import { hasAccessToAdminRoute } from "@/const/admin-routes";
+import { canEditForm } from "@/lib/access-control";
// ... existing code ...
export async function checkFormEditAccess(formId: string) {
const db_user = await api.user.me();
if (!db_user?.role_config) {
redirect("/dashboard");
}
if (db_user.role_config.isTotem) {
redirect("/dashboard");
}
const form = await api.form.getById(formId);
if (!form || !db_user.id) {
redirect("/forms");
}
- const canEdit =- form.userId === db_user.id ||- form.ownerIds?.includes(db_user.id) ||- db_user.role_config.sudo ||- db_user.role_config.can_create_form;+ const canEdit = canEditForm(+ db_user.role_config,+ db_user.id,+ formId,+ form,+ db_user.setor+ );
if (!canEdit) {
redirect("/forms");
}
return db_user;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/access-control-server.ts` around lines 144 - 156, Replace the
duplicated permission logic with the centralized canEditForm function: import
canEditForm from '@/lib/access-control' and use it to compute permission (e.g.,
const canEdit = canEditForm({ form, user: db_user })); then keep the same
redirect behavior when !form or !db_user.id and when !canEdit so behavior is
unchanged; update or remove the existing manual checks (form.userId,
form.ownerIds, db_user.role_config) in access-control-server.ts to rely on
canEditForm instead.
vitest.config.ts (1)

5-8: Consider jsdom environment for React component tests.

The environment: "node" setting works for server-side tests like access-control, but .tsx tests that render React components will require jsdom. If component tests are added later, you may need to configure per-file environments.

💡 Example for future component tests
// For per-file environment configuration, add at the top of component test files:// `@vitest-environment` jsdom// Or configure in vitest.config.ts with environmentMatchGlobs:
test: {environment: "node",environmentMatchGlobs: [["src/components/**/*.test.tsx","jsdom"],],// ...}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@vitest.config.ts` around lines 5 - 8, The test config currently sets
environment: "node" which will break React .tsx component tests; update the
Vitest test config block (the test object that contains environment) to add
per-file environment rules by adding environmentMatchGlobs mapping (key:
environmentMatchGlobs) that maps your component test glob(s) like
"src/components/**/*.test.tsx" to "jsdom", or alternatively document adding a //
`@vitest-environment` jsdom header in individual component test files so .tsx
tests run under jsdom while keeping the default environment as node.
src/lib/__tests__/access-control.forms-edit.test.ts (1)

2-2: Use the @/ alias for this internal import.

../access-control breaks the repo’s import convention and is more brittle than the configured alias.

As per coding guidelines, "Always use @/ aliases for internal imports instead of relative paths".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/__tests__/access-control.forms-edit.test.ts` at line 2, Replace the
relative import "../access-control" with the project alias import using
"@/access-control" in the test file so it follows the repo convention; locate
the import line that imports canEditForm and change it to use the "@/..." alias
(i.e., import { canEditForm } from "@/access-control") so the test uses the
configured internal path alias.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/lib/__tests__/access-control.forms-edit.test.ts`:
- Around line 111-144: The test and permission logic incorrectly treat
role_config.can_create_form as permission to edit any form; update the
canEditForm implementation so can_create_form does NOT grant edit-any
rights—only sudo or explicit ownership (userId === form.userId or form.ownerIds
includes userId) or explicit edit permissions should allow editing—and then
change the failing tests in access-control.forms-edit.test.ts to assert false
for a non-owner/non-sudo user with only can_create_form true; keep true
expectations only for sudo or actual owner scenarios and adjust references to
canEditForm, role_config.can_create_form, sudo, userId, form.userId, and
form.ownerIds accordingly.
---
Nitpick comments:
In `@src/lib/__tests__/access-control.forms-edit.test.ts`:
- Line 2: Replace the relative import "../access-control" with the project alias
import using "@/access-control" in the test file so it follows the repo
convention; locate the import line that imports canEditForm and change it to use
the "@/..." alias (i.e., import { canEditForm } from "@/access-control") so the
test uses the configured internal path alias.
In `@src/lib/access-control-server.ts`:
- Around line 144-156: Replace the duplicated permission logic with the
centralized canEditForm function: import canEditForm from '@/lib/access-control'
and use it to compute permission (e.g., const canEdit = canEditForm({ form,
user: db_user })); then keep the same redirect behavior when !form or
!db_user.id and when !canEdit so behavior is unchanged; update or remove the
existing manual checks (form.userId, form.ownerIds, db_user.role_config) in
access-control-server.ts to rely on canEditForm instead.
In `@src/lib/date-utils.ts`:
- Around line 1-10: Add JSDoc comments to both exported functions
isSameUtcMonthDay and getUtcMonthDay: include `@param` tags describing the Date
parameters, an `@returns` tag explaining the boolean result for isSameUtcMonthDay
and the { month:number; day:number } shape for getUtcMonthDay, and add a brief
`@example` showing usage; keep the explicit return types (boolean and { month:
number; day: number }) on the function signatures and ensure the comments sit
immediately above each function declaration.
In `@vitest.config.ts`:
- Around line 5-8: The test config currently sets environment: "node" which will
break React .tsx component tests; update the Vitest test config block (the test
object that contains environment) to add per-file environment rules by adding
environmentMatchGlobs mapping (key: environmentMatchGlobs) that maps your
component test glob(s) like "src/components/**/*.test.tsx" to "jsdom", or
alternatively document adding a // `@vitest-environment` jsdom header in
individual component test files so .tsx tests run under jsdom while keeping the
default environment as node.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a5d8c30e-237a-4587-87b3-be9c464ce26b

📥 Commits

Reviewing files that changed from the base of the PR and between 754cd4b and b5042b5.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • package.json
  • src/components/birthday/birthday-confetti-wrapper.tsx
  • src/components/birthday/birthday-confetti.tsx
  • src/lib/__tests__/access-control.forms-edit.test.ts
  • src/lib/access-control-server.ts
  • src/lib/access-control.ts
  • src/lib/date-utils.ts
  • src/server/api/routers/forms.ts
  • vitest.config.ts

Comment on lines +111 to +144
describe("sudo e can_create_form podem editar qualquer formulário", () => {
it("retorna true quando role_config.sudo é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, sudo: true },
otherUserId,
formId,
{
userId: creatorId,
ownerIds: [ownerId],
isPrivate: true,
allowedUsers: [],
allowedSectors: [],
},
null
);
expect(result).toBe(true);
});

it("retorna true quando role_config.can_create_form é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, can_create_form: true },
otherUserId,
formId,
{
userId: creatorId,
ownerIds: [],
isPrivate: false,
allowedUsers: [],
allowedSectors: [],
},
null
);
expect(result).toBe(true);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Don’t lock in can_create_form as edit-any-form permission.

This test suite codifies the privilege escalation the PR is trying to close. If can_create_form alone returns true here, any user with form-creation rights can still modify unrelated — including private — forms they do not own.

🔐 Suggested test update
- describe("sudo e can_create_form podem editar qualquer formulário", () => {+ describe("apenas sudo pode editar qualquer formulário", () => {
it("retorna true quando role_config.sudo é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, sudo: true },
otherUserId,
formId,
@@
);
expect(result).toBe(true);
});
- it("retorna true quando role_config.can_create_form é true", () => {+ it("retorna false quando role_config.can_create_form é true, mas o usuário não é owner/criador", () => {
const result = canEditForm(
{ ...baseRoleConfig, can_create_form: true },
otherUserId,
formId,
@@
null
);
- expect(result).toBe(true);+ expect(result).toBe(false);
});
});

As per coding guidelines, "Implement permission checks in API procedures, throwing FORBIDDEN errors when users lack sudo privileges or attempt to modify resources they don't own".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/__tests__/access-control.forms-edit.test.ts` around lines 111 - 144,
The test and permission logic incorrectly treat role_config.can_create_form as
permission to edit any form; update the canEditForm implementation so
can_create_form does NOT grant edit-any rights—only sudo or explicit ownership
(userId === form.userId or form.ownerIds includes userId) or explicit edit
permissions should allow editing—and then change the failing tests in
access-control.forms-edit.test.ts to assert false for a non-owner/non-sudo user
with only can_create_form true; keep true expectations only for sudo or actual
owner scenarios and adjust references to canEditForm,
role_config.can_create_form, sudo, userId, form.userId, and form.ownerIds
accordingly.

@GRHInvDev
GRHInvDev merged commit 36d051a into mainMar 10, 2026
7 of 9 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

INTRANET - Ajustar data no conffetti para puxar a data correta!

2 participants

@rbxyz@GRHInvDev
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

347 erro de permisionamento! - #348

Merged
GRHInvDev merged 2 commits into
mainfrom
347-ajustar-data-no-conffetti-para-puxar-a-data-correta
Mar 10, 2026
Merged

347 erro de permisionamento!#348
GRHInvDev merged 2 commits into
mainfrom
347-ajustar-data-no-conffetti-para-puxar-a-data-correta

Conversation

@rbxyz

@rbxyzrbxyz commented Mar 9, 2026

Copy link
Copy Markdown
Collaborator

Foi identificado hoje mais cedo um erro de permissão!
Um dos usuários conseguiu alterar um dos formulários sem a devida permissão!
O usuário Roger alterou o formulário de TI, inserindo acidentalmente no formulário o próprio nome!
Isso pode afetar formulários privados!

Summary by CodeRabbit

  • Bug Fixes

    • Fixed birthday detection to use UTC time for consistent behavior across timezones.
  • Improvements

    • Streamlined form editing permissions and simplified access control authorization rules.
  • Tests

    • Added comprehensive test coverage for form editing permissions and access control scenarios.

@rbxyzrbxyz linked an issue Mar 9, 2026 that may be closed by this pull request
@vercel

vercelBot commented Mar 9, 2026

Copy link
Copy Markdown

Deployment failed with the following error:

You don't have permission to create a Preview Deployment for this Vercel project: elo.

View Documentation: https://vercel.com/docs/accounts/team-members-and-roles

@rbxyzrbxyz self-assigned this Mar 9, 2026
@coderabbitai

coderabbitaiBot commented Mar 9, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The PR introduces testing infrastructure via Vitest, adds UTC-based date utilities for birthday comparisons, and simplifies form access control logic by removing private-form and sector-based permission checks while retaining creator, owner, and sudo-based authorization.

Changes

Cohort / File(s)Summary
Testing Infrastructure
package.json, vitest.config.ts
Added Vitest v2.1.0 as dev dependency with test and test:watch scripts; configured Vitest to use node environment with path aliases and test file patterns.
UTC Date Utilities
src/lib/date-utils.ts
Introduced two UTC-based date helper functions: isSameUtcMonthDay() for comparing month/day in UTC, and getUtcMonthDay() for extracting UTC month and day from dates.
Birthday Components
src/components/birthday/birthday-confetti.tsx, src/components/birthday/birthday-confetti-wrapper.tsx
Refactored birthday comparison logic to use isSameUtcMonthDay() helper instead of manual local date comparison; updated comments to reflect UTC semantics.
Access Control Refactor
src/lib/access-control.ts, src/lib/access-control-server.ts, src/server/api/routers/forms.ts
Simplified canEditForm() function by removing private-form, allowedUsers, and allowedSectors checks; now only grants edit access to creators, explicit owners, sudo users, or those with can_create_form flag. Updated form router update mutation to use consolidated canEditForm() call.
Access Control Test Coverage
src/lib/__tests__/access-control.forms-edit.test.ts
Added comprehensive unit test suite for canEditForm() covering creator/owner privileges, sudo and can_create_form flags, public/private form scenarios, and edge cases with null configs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 Hops with glee at UTC dates so bright,
Vitest runs the tests through the night,
Access controls trimmed with care,
Simpler logic fills the air!
Confetti springs from cleaner code,
Along the testing rabbit road. 🎂✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 25.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check❓ InconclusiveThe PR title '347 erro de permisionamento!' references a permission error issue but does not clearly summarize the actual changes made in the changeset.Update the title to clearly describe the main changes: consolidating permission checks in canEditForm, adding UTC date utilities, or fixing form edit authorization logic.
✅ Passed checks (1 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 347-ajustar-data-no-conffetti-para-puxar-a-data-correta

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
src/lib/date-utils.ts (1)

1-10: Add JSDoc documentation and explicit return types.

Per coding guidelines, public utility functions should have JSDoc comments with @param and @returns tags, and explicit return types.

📝 Proposed documentation and typing improvements
+/**+ * Compares two dates to check if they share the same UTC month and day.+ * `@param` a - First date to compare+ * `@param` b - Second date to compare+ * `@returns` true if both dates have the same UTC month and day+ * `@example`+ * isSameUtcMonthDay(new Date('2024-01-15'), new Date('2025-01-15')) // true+ */-export function isSameUtcMonthDay(a: Date, b: Date): boolean {+export function isSameUtcMonthDay(a: Date, b: Date): boolean {
return a.getUTCMonth() === b.getUTCMonth() && a.getUTCDate() === b.getUTCDate()
}
+/**+ * Extracts the UTC month and day from a date object.+ * `@param` date - The date to extract from+ * `@returns` Object containing UTC month (0-11) and day (1-31)+ */
export function getUtcMonthDay(date: Date): { month: number; day: number } {
return {
month: date.getUTCMonth(),
day: date.getUTCDate(),
}
}

As per coding guidelines: "Document functions and components with JSDoc comments including @param and @returns" and "Use JSDoc comments for all public functions and hooks with @param, @returns, and @example tags."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/date-utils.ts` around lines 1 - 10, Add JSDoc comments to both
exported functions isSameUtcMonthDay and getUtcMonthDay: include `@param` tags
describing the Date parameters, an `@returns` tag explaining the boolean result
for isSameUtcMonthDay and the { month:number; day:number } shape for
getUtcMonthDay, and add a brief `@example` showing usage; keep the explicit return
types (boolean and { month: number; day: number }) on the function signatures
and ensure the comments sit immediately above each function declaration.
src/lib/access-control-server.ts (1)

144-156: Consider using canEditForm to avoid logic duplication.

The permission logic here duplicates canEditForm from @/lib/access-control. This creates a maintenance risk if the permission rules change. Consider importing and using canEditForm directly.

♻️ Proposed refactor to use centralized permission check
 import "server-only";
import { redirect } from "next/navigation";
import { api } from "@/trpc/server";
import { hasAccessToAdminRoute } from "@/const/admin-routes";
+import { canEditForm } from "@/lib/access-control";
// ... existing code ...
export async function checkFormEditAccess(formId: string) {
const db_user = await api.user.me();
if (!db_user?.role_config) {
redirect("/dashboard");
}
if (db_user.role_config.isTotem) {
redirect("/dashboard");
}
const form = await api.form.getById(formId);
if (!form || !db_user.id) {
redirect("/forms");
}
- const canEdit =- form.userId === db_user.id ||- form.ownerIds?.includes(db_user.id) ||- db_user.role_config.sudo ||- db_user.role_config.can_create_form;+ const canEdit = canEditForm(+ db_user.role_config,+ db_user.id,+ formId,+ form,+ db_user.setor+ );
if (!canEdit) {
redirect("/forms");
}
return db_user;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/access-control-server.ts` around lines 144 - 156, Replace the
duplicated permission logic with the centralized canEditForm function: import
canEditForm from '@/lib/access-control' and use it to compute permission (e.g.,
const canEdit = canEditForm({ form, user: db_user })); then keep the same
redirect behavior when !form or !db_user.id and when !canEdit so behavior is
unchanged; update or remove the existing manual checks (form.userId,
form.ownerIds, db_user.role_config) in access-control-server.ts to rely on
canEditForm instead.
vitest.config.ts (1)

5-8: Consider jsdom environment for React component tests.

The environment: "node" setting works for server-side tests like access-control, but .tsx tests that render React components will require jsdom. If component tests are added later, you may need to configure per-file environments.

💡 Example for future component tests
// For per-file environment configuration, add at the top of component test files:// `@vitest-environment` jsdom// Or configure in vitest.config.ts with environmentMatchGlobs:
test: {environment: "node",environmentMatchGlobs: [["src/components/**/*.test.tsx","jsdom"],],// ...}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@vitest.config.ts` around lines 5 - 8, The test config currently sets
environment: "node" which will break React .tsx component tests; update the
Vitest test config block (the test object that contains environment) to add
per-file environment rules by adding environmentMatchGlobs mapping (key:
environmentMatchGlobs) that maps your component test glob(s) like
"src/components/**/*.test.tsx" to "jsdom", or alternatively document adding a //
`@vitest-environment` jsdom header in individual component test files so .tsx
tests run under jsdom while keeping the default environment as node.
src/lib/__tests__/access-control.forms-edit.test.ts (1)

2-2: Use the @/ alias for this internal import.

../access-control breaks the repo’s import convention and is more brittle than the configured alias.

As per coding guidelines, "Always use @/ aliases for internal imports instead of relative paths".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/__tests__/access-control.forms-edit.test.ts` at line 2, Replace the
relative import "../access-control" with the project alias import using
"@/access-control" in the test file so it follows the repo convention; locate
the import line that imports canEditForm and change it to use the "@/..." alias
(i.e., import { canEditForm } from "@/access-control") so the test uses the
configured internal path alias.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/lib/__tests__/access-control.forms-edit.test.ts`:
- Around line 111-144: The test and permission logic incorrectly treat
role_config.can_create_form as permission to edit any form; update the
canEditForm implementation so can_create_form does NOT grant edit-any
rights—only sudo or explicit ownership (userId === form.userId or form.ownerIds
includes userId) or explicit edit permissions should allow editing—and then
change the failing tests in access-control.forms-edit.test.ts to assert false
for a non-owner/non-sudo user with only can_create_form true; keep true
expectations only for sudo or actual owner scenarios and adjust references to
canEditForm, role_config.can_create_form, sudo, userId, form.userId, and
form.ownerIds accordingly.
---
Nitpick comments:
In `@src/lib/__tests__/access-control.forms-edit.test.ts`:
- Line 2: Replace the relative import "../access-control" with the project alias
import using "@/access-control" in the test file so it follows the repo
convention; locate the import line that imports canEditForm and change it to use
the "@/..." alias (i.e., import { canEditForm } from "@/access-control") so the
test uses the configured internal path alias.
In `@src/lib/access-control-server.ts`:
- Around line 144-156: Replace the duplicated permission logic with the
centralized canEditForm function: import canEditForm from '@/lib/access-control'
and use it to compute permission (e.g., const canEdit = canEditForm({ form,
user: db_user })); then keep the same redirect behavior when !form or
!db_user.id and when !canEdit so behavior is unchanged; update or remove the
existing manual checks (form.userId, form.ownerIds, db_user.role_config) in
access-control-server.ts to rely on canEditForm instead.
In `@src/lib/date-utils.ts`:
- Around line 1-10: Add JSDoc comments to both exported functions
isSameUtcMonthDay and getUtcMonthDay: include `@param` tags describing the Date
parameters, an `@returns` tag explaining the boolean result for isSameUtcMonthDay
and the { month:number; day:number } shape for getUtcMonthDay, and add a brief
`@example` showing usage; keep the explicit return types (boolean and { month:
number; day: number }) on the function signatures and ensure the comments sit
immediately above each function declaration.
In `@vitest.config.ts`:
- Around line 5-8: The test config currently sets environment: "node" which will
break React .tsx component tests; update the Vitest test config block (the test
object that contains environment) to add per-file environment rules by adding
environmentMatchGlobs mapping (key: environmentMatchGlobs) that maps your
component test glob(s) like "src/components/**/*.test.tsx" to "jsdom", or
alternatively document adding a // `@vitest-environment` jsdom header in
individual component test files so .tsx tests run under jsdom while keeping the
default environment as node.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a5d8c30e-237a-4587-87b3-be9c464ce26b

📥 Commits

Reviewing files that changed from the base of the PR and between 754cd4b and b5042b5.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • package.json
  • src/components/birthday/birthday-confetti-wrapper.tsx
  • src/components/birthday/birthday-confetti.tsx
  • src/lib/__tests__/access-control.forms-edit.test.ts
  • src/lib/access-control-server.ts
  • src/lib/access-control.ts
  • src/lib/date-utils.ts
  • src/server/api/routers/forms.ts
  • vitest.config.ts

Comment on lines +111 to +144
describe("sudo e can_create_form podem editar qualquer formulário", () => {
it("retorna true quando role_config.sudo é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, sudo: true },
otherUserId,
formId,
{
userId: creatorId,
ownerIds: [ownerId],
isPrivate: true,
allowedUsers: [],
allowedSectors: [],
},
null
);
expect(result).toBe(true);
});

it("retorna true quando role_config.can_create_form é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, can_create_form: true },
otherUserId,
formId,
{
userId: creatorId,
ownerIds: [],
isPrivate: false,
allowedUsers: [],
allowedSectors: [],
},
null
);
expect(result).toBe(true);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Don’t lock in can_create_form as edit-any-form permission.

This test suite codifies the privilege escalation the PR is trying to close. If can_create_form alone returns true here, any user with form-creation rights can still modify unrelated — including private — forms they do not own.

🔐 Suggested test update
- describe("sudo e can_create_form podem editar qualquer formulário", () => {+ describe("apenas sudo pode editar qualquer formulário", () => {
it("retorna true quando role_config.sudo é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, sudo: true },
otherUserId,
formId,
@@
);
expect(result).toBe(true);
});
- it("retorna true quando role_config.can_create_form é true", () => {+ it("retorna false quando role_config.can_create_form é true, mas o usuário não é owner/criador", () => {
const result = canEditForm(
{ ...baseRoleConfig, can_create_form: true },
otherUserId,
formId,
@@
null
);
- expect(result).toBe(true);+ expect(result).toBe(false);
});
});

As per coding guidelines, "Implement permission checks in API procedures, throwing FORBIDDEN errors when users lack sudo privileges or attempt to modify resources they don't own".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/__tests__/access-control.forms-edit.test.ts` around lines 111 - 144,
The test and permission logic incorrectly treat role_config.can_create_form as
permission to edit any form; update the canEditForm implementation so
can_create_form does NOT grant edit-any rights—only sudo or explicit ownership
(userId === form.userId or form.ownerIds includes userId) or explicit edit
permissions should allow editing—and then change the failing tests in
access-control.forms-edit.test.ts to assert false for a non-owner/non-sudo user
with only can_create_form true; keep true expectations only for sudo or actual
owner scenarios and adjust references to canEditForm,
role_config.can_create_form, sudo, userId, form.userId, and form.ownerIds
accordingly.

@GRHInvDev
GRHInvDev merged commit 36d051a into mainMar 10, 2026
7 of 9 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

INTRANET - Ajustar data no conffetti para puxar a data correta!

2 participants

@rbxyz@GRHInvDev
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

347 erro de permisionamento! - #348

Merged
GRHInvDev merged 2 commits into
mainfrom
347-ajustar-data-no-conffetti-para-puxar-a-data-correta
Mar 10, 2026
Merged

347 erro de permisionamento!#348
GRHInvDev merged 2 commits into
mainfrom
347-ajustar-data-no-conffetti-para-puxar-a-data-correta

Conversation

@rbxyz

@rbxyzrbxyz commented Mar 9, 2026

Copy link
Copy Markdown
Collaborator

Foi identificado hoje mais cedo um erro de permissão!
Um dos usuários conseguiu alterar um dos formulários sem a devida permissão!
O usuário Roger alterou o formulário de TI, inserindo acidentalmente no formulário o próprio nome!
Isso pode afetar formulários privados!

Summary by CodeRabbit

  • Bug Fixes

    • Fixed birthday detection to use UTC time for consistent behavior across timezones.
  • Improvements

    • Streamlined form editing permissions and simplified access control authorization rules.
  • Tests

    • Added comprehensive test coverage for form editing permissions and access control scenarios.

@rbxyzrbxyz linked an issue Mar 9, 2026 that may be closed by this pull request
@vercel

vercelBot commented Mar 9, 2026

Copy link
Copy Markdown

Deployment failed with the following error:

You don't have permission to create a Preview Deployment for this Vercel project: elo.

View Documentation: https://vercel.com/docs/accounts/team-members-and-roles

@rbxyzrbxyz self-assigned this Mar 9, 2026
@coderabbitai

coderabbitaiBot commented Mar 9, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The PR introduces testing infrastructure via Vitest, adds UTC-based date utilities for birthday comparisons, and simplifies form access control logic by removing private-form and sector-based permission checks while retaining creator, owner, and sudo-based authorization.

Changes

Cohort / File(s)Summary
Testing Infrastructure
package.json, vitest.config.ts
Added Vitest v2.1.0 as dev dependency with test and test:watch scripts; configured Vitest to use node environment with path aliases and test file patterns.
UTC Date Utilities
src/lib/date-utils.ts
Introduced two UTC-based date helper functions: isSameUtcMonthDay() for comparing month/day in UTC, and getUtcMonthDay() for extracting UTC month and day from dates.
Birthday Components
src/components/birthday/birthday-confetti.tsx, src/components/birthday/birthday-confetti-wrapper.tsx
Refactored birthday comparison logic to use isSameUtcMonthDay() helper instead of manual local date comparison; updated comments to reflect UTC semantics.
Access Control Refactor
src/lib/access-control.ts, src/lib/access-control-server.ts, src/server/api/routers/forms.ts
Simplified canEditForm() function by removing private-form, allowedUsers, and allowedSectors checks; now only grants edit access to creators, explicit owners, sudo users, or those with can_create_form flag. Updated form router update mutation to use consolidated canEditForm() call.
Access Control Test Coverage
src/lib/__tests__/access-control.forms-edit.test.ts
Added comprehensive unit test suite for canEditForm() covering creator/owner privileges, sudo and can_create_form flags, public/private form scenarios, and edge cases with null configs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 Hops with glee at UTC dates so bright,
Vitest runs the tests through the night,
Access controls trimmed with care,
Simpler logic fills the air!
Confetti springs from cleaner code,
Along the testing rabbit road. 🎂✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 25.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check❓ InconclusiveThe PR title '347 erro de permisionamento!' references a permission error issue but does not clearly summarize the actual changes made in the changeset.Update the title to clearly describe the main changes: consolidating permission checks in canEditForm, adding UTC date utilities, or fixing form edit authorization logic.
✅ Passed checks (1 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 347-ajustar-data-no-conffetti-para-puxar-a-data-correta

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
src/lib/date-utils.ts (1)

1-10: Add JSDoc documentation and explicit return types.

Per coding guidelines, public utility functions should have JSDoc comments with @param and @returns tags, and explicit return types.

📝 Proposed documentation and typing improvements
+/**+ * Compares two dates to check if they share the same UTC month and day.+ * `@param` a - First date to compare+ * `@param` b - Second date to compare+ * `@returns` true if both dates have the same UTC month and day+ * `@example`+ * isSameUtcMonthDay(new Date('2024-01-15'), new Date('2025-01-15')) // true+ */-export function isSameUtcMonthDay(a: Date, b: Date): boolean {+export function isSameUtcMonthDay(a: Date, b: Date): boolean {
return a.getUTCMonth() === b.getUTCMonth() && a.getUTCDate() === b.getUTCDate()
}
+/**+ * Extracts the UTC month and day from a date object.+ * `@param` date - The date to extract from+ * `@returns` Object containing UTC month (0-11) and day (1-31)+ */
export function getUtcMonthDay(date: Date): { month: number; day: number } {
return {
month: date.getUTCMonth(),
day: date.getUTCDate(),
}
}

As per coding guidelines: "Document functions and components with JSDoc comments including @param and @returns" and "Use JSDoc comments for all public functions and hooks with @param, @returns, and @example tags."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/date-utils.ts` around lines 1 - 10, Add JSDoc comments to both
exported functions isSameUtcMonthDay and getUtcMonthDay: include `@param` tags
describing the Date parameters, an `@returns` tag explaining the boolean result
for isSameUtcMonthDay and the { month:number; day:number } shape for
getUtcMonthDay, and add a brief `@example` showing usage; keep the explicit return
types (boolean and { month: number; day: number }) on the function signatures
and ensure the comments sit immediately above each function declaration.
src/lib/access-control-server.ts (1)

144-156: Consider using canEditForm to avoid logic duplication.

The permission logic here duplicates canEditForm from @/lib/access-control. This creates a maintenance risk if the permission rules change. Consider importing and using canEditForm directly.

♻️ Proposed refactor to use centralized permission check
 import "server-only";
import { redirect } from "next/navigation";
import { api } from "@/trpc/server";
import { hasAccessToAdminRoute } from "@/const/admin-routes";
+import { canEditForm } from "@/lib/access-control";
// ... existing code ...
export async function checkFormEditAccess(formId: string) {
const db_user = await api.user.me();
if (!db_user?.role_config) {
redirect("/dashboard");
}
if (db_user.role_config.isTotem) {
redirect("/dashboard");
}
const form = await api.form.getById(formId);
if (!form || !db_user.id) {
redirect("/forms");
}
- const canEdit =- form.userId === db_user.id ||- form.ownerIds?.includes(db_user.id) ||- db_user.role_config.sudo ||- db_user.role_config.can_create_form;+ const canEdit = canEditForm(+ db_user.role_config,+ db_user.id,+ formId,+ form,+ db_user.setor+ );
if (!canEdit) {
redirect("/forms");
}
return db_user;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/access-control-server.ts` around lines 144 - 156, Replace the
duplicated permission logic with the centralized canEditForm function: import
canEditForm from '@/lib/access-control' and use it to compute permission (e.g.,
const canEdit = canEditForm({ form, user: db_user })); then keep the same
redirect behavior when !form or !db_user.id and when !canEdit so behavior is
unchanged; update or remove the existing manual checks (form.userId,
form.ownerIds, db_user.role_config) in access-control-server.ts to rely on
canEditForm instead.
vitest.config.ts (1)

5-8: Consider jsdom environment for React component tests.

The environment: "node" setting works for server-side tests like access-control, but .tsx tests that render React components will require jsdom. If component tests are added later, you may need to configure per-file environments.

💡 Example for future component tests
// For per-file environment configuration, add at the top of component test files:// `@vitest-environment` jsdom// Or configure in vitest.config.ts with environmentMatchGlobs:
test: {environment: "node",environmentMatchGlobs: [["src/components/**/*.test.tsx","jsdom"],],// ...}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@vitest.config.ts` around lines 5 - 8, The test config currently sets
environment: "node" which will break React .tsx component tests; update the
Vitest test config block (the test object that contains environment) to add
per-file environment rules by adding environmentMatchGlobs mapping (key:
environmentMatchGlobs) that maps your component test glob(s) like
"src/components/**/*.test.tsx" to "jsdom", or alternatively document adding a //
`@vitest-environment` jsdom header in individual component test files so .tsx
tests run under jsdom while keeping the default environment as node.
src/lib/__tests__/access-control.forms-edit.test.ts (1)

2-2: Use the @/ alias for this internal import.

../access-control breaks the repo’s import convention and is more brittle than the configured alias.

As per coding guidelines, "Always use @/ aliases for internal imports instead of relative paths".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/__tests__/access-control.forms-edit.test.ts` at line 2, Replace the
relative import "../access-control" with the project alias import using
"@/access-control" in the test file so it follows the repo convention; locate
the import line that imports canEditForm and change it to use the "@/..." alias
(i.e., import { canEditForm } from "@/access-control") so the test uses the
configured internal path alias.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/lib/__tests__/access-control.forms-edit.test.ts`:
- Around line 111-144: The test and permission logic incorrectly treat
role_config.can_create_form as permission to edit any form; update the
canEditForm implementation so can_create_form does NOT grant edit-any
rights—only sudo or explicit ownership (userId === form.userId or form.ownerIds
includes userId) or explicit edit permissions should allow editing—and then
change the failing tests in access-control.forms-edit.test.ts to assert false
for a non-owner/non-sudo user with only can_create_form true; keep true
expectations only for sudo or actual owner scenarios and adjust references to
canEditForm, role_config.can_create_form, sudo, userId, form.userId, and
form.ownerIds accordingly.
---
Nitpick comments:
In `@src/lib/__tests__/access-control.forms-edit.test.ts`:
- Line 2: Replace the relative import "../access-control" with the project alias
import using "@/access-control" in the test file so it follows the repo
convention; locate the import line that imports canEditForm and change it to use
the "@/..." alias (i.e., import { canEditForm } from "@/access-control") so the
test uses the configured internal path alias.
In `@src/lib/access-control-server.ts`:
- Around line 144-156: Replace the duplicated permission logic with the
centralized canEditForm function: import canEditForm from '@/lib/access-control'
and use it to compute permission (e.g., const canEdit = canEditForm({ form,
user: db_user })); then keep the same redirect behavior when !form or
!db_user.id and when !canEdit so behavior is unchanged; update or remove the
existing manual checks (form.userId, form.ownerIds, db_user.role_config) in
access-control-server.ts to rely on canEditForm instead.
In `@src/lib/date-utils.ts`:
- Around line 1-10: Add JSDoc comments to both exported functions
isSameUtcMonthDay and getUtcMonthDay: include `@param` tags describing the Date
parameters, an `@returns` tag explaining the boolean result for isSameUtcMonthDay
and the { month:number; day:number } shape for getUtcMonthDay, and add a brief
`@example` showing usage; keep the explicit return types (boolean and { month:
number; day: number }) on the function signatures and ensure the comments sit
immediately above each function declaration.
In `@vitest.config.ts`:
- Around line 5-8: The test config currently sets environment: "node" which will
break React .tsx component tests; update the Vitest test config block (the test
object that contains environment) to add per-file environment rules by adding
environmentMatchGlobs mapping (key: environmentMatchGlobs) that maps your
component test glob(s) like "src/components/**/*.test.tsx" to "jsdom", or
alternatively document adding a // `@vitest-environment` jsdom header in
individual component test files so .tsx tests run under jsdom while keeping the
default environment as node.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a5d8c30e-237a-4587-87b3-be9c464ce26b

📥 Commits

Reviewing files that changed from the base of the PR and between 754cd4b and b5042b5.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • package.json
  • src/components/birthday/birthday-confetti-wrapper.tsx
  • src/components/birthday/birthday-confetti.tsx
  • src/lib/__tests__/access-control.forms-edit.test.ts
  • src/lib/access-control-server.ts
  • src/lib/access-control.ts
  • src/lib/date-utils.ts
  • src/server/api/routers/forms.ts
  • vitest.config.ts

Comment on lines +111 to +144
describe("sudo e can_create_form podem editar qualquer formulário", () => {
it("retorna true quando role_config.sudo é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, sudo: true },
otherUserId,
formId,
{
userId: creatorId,
ownerIds: [ownerId],
isPrivate: true,
allowedUsers: [],
allowedSectors: [],
},
null
);
expect(result).toBe(true);
});

it("retorna true quando role_config.can_create_form é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, can_create_form: true },
otherUserId,
formId,
{
userId: creatorId,
ownerIds: [],
isPrivate: false,
allowedUsers: [],
allowedSectors: [],
},
null
);
expect(result).toBe(true);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Don’t lock in can_create_form as edit-any-form permission.

This test suite codifies the privilege escalation the PR is trying to close. If can_create_form alone returns true here, any user with form-creation rights can still modify unrelated — including private — forms they do not own.

🔐 Suggested test update
- describe("sudo e can_create_form podem editar qualquer formulário", () => {+ describe("apenas sudo pode editar qualquer formulário", () => {
it("retorna true quando role_config.sudo é true", () => {
const result = canEditForm(
{ ...baseRoleConfig, sudo: true },
otherUserId,
formId,
@@
);
expect(result).toBe(true);
});
- it("retorna true quando role_config.can_create_form é true", () => {+ it("retorna false quando role_config.can_create_form é true, mas o usuário não é owner/criador", () => {
const result = canEditForm(
{ ...baseRoleConfig, can_create_form: true },
otherUserId,
formId,
@@
null
);
- expect(result).toBe(true);+ expect(result).toBe(false);
});
});

As per coding guidelines, "Implement permission checks in API procedures, throwing FORBIDDEN errors when users lack sudo privileges or attempt to modify resources they don't own".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/__tests__/access-control.forms-edit.test.ts` around lines 111 - 144,
The test and permission logic incorrectly treat role_config.can_create_form as
permission to edit any form; update the canEditForm implementation so
can_create_form does NOT grant edit-any rights—only sudo or explicit ownership
(userId === form.userId or form.ownerIds includes userId) or explicit edit
permissions should allow editing—and then change the failing tests in
access-control.forms-edit.test.ts to assert false for a non-owner/non-sudo user
with only can_create_form true; keep true expectations only for sudo or actual
owner scenarios and adjust references to canEditForm,
role_config.can_create_form, sudo, userId, form.userId, and form.ownerIds
accordingly.

@GRHInvDev
GRHInvDev merged commit 36d051a into mainMar 10, 2026
7 of 9 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

INTRANET - Ajustar data no conffetti para puxar a data correta!

2 participants

@rbxyz@GRHInvDev