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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,10 @@ POSTIZ_OAUTH_CLIENT_SECRET=""
# LINK_DRIP_API_ENDPOINT="https://api.linkdrip.com/v1/" # Your self-hosted LinkDrip API endpoint
# LINK_DRIP_SHORT_LINK_DOMAIN="dripl.ink" # Your self-hosted LinkDrip domain

# reCAPTCHA Settings (invisible v2 on anonymous preview comments, optional; unset = no captcha)
# RECAPTCHA_SITE_KEY="" # Your reCAPTCHA v2 invisible site key
# RECAPTCHA_SECRET_KEY="" # Your reCAPTCHA v2 invisible secret key

# Provider visibility / migration
# HIDDEN_PROVIDERS="tiktok" # comma-separated identifiers hidden from the add-channel screen
# MIGRATE_PROVIDERS="tiktok:tiktok-business" # comma-separated "old:new" pairs, a reconnect of "old" goes through "new" and the channel is migrated in place
25 changes: 21 additions & 4 deletions apps/backend/src/api/routes/posts.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ import {
Sections,
} from '@gitroom/backend/services/auth/permissions/permission.exception.class';
import { PostValidationException } from '@gitroom/backend/api/routes/posts.validation.exception';
import {
CreatePublicCommentDto,
ResolveCommentDto,
} from '@gitroom/nestjs-libraries/dtos/comments/add.comment.dto';
import { RealIP } from 'nestjs-real-ip';

@ApiTags('Posts')
@Controller('/posts')
Expand Down Expand Up @@ -71,12 +76,21 @@ export class PostsController {

@Post('/:id/comments')
async createComment(
@GetOrgFromRequest() org: Organization,
@GetUserFromRequest() user: User,
@Param('id') id: string,
@Body() body: { comment: string }
@Body() body: CreatePublicCommentDto,
@RealIP() ip: string
) {
return this._postsService.createComment(org.id, user.id, id, body.comment);
return this._postsService.createPublicComment(id, body, user.id, ip);
Comment on lines 80 to +84

This comment was marked as outdated.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This is intended. Preview links are public and the feature is built so that anyone with the link can comment, including people outside the organization such as clients and sponsors, signed in or not. The new public route accepts anonymous comments on any post the visitor has the link for, so a signed in user from another organization gains nothing extra through this route; their comment just carries their profile name instead of a typed one. The previous version of this endpoint had no check that the post belongs to the caller's organization either; it only stamped the caller's organization id on the comment, which stored the wrong id. The service now takes the organization from the post itself. Actions that must stay scoped are checked: resolving a thread verifies that the comment's post belongs to the caller's organization and returns 404 otherwise.

}

@Put('/comments/:commentId/resolve')
async resolveComment(
@GetOrgFromRequest() org: Organization,
@Param('commentId') commentId: string,
@Body() body: ResolveCommentDto
) {
return this._postsService.resolveComment(org.id, commentId, body.resolved);
}

@Get('/tags')
Expand Down Expand Up @@ -159,7 +173,10 @@ export class PostsController {
}

@Get('/group/:group')
getPostsByGroup(@GetOrgFromRequest() org: Organization, @Param('group') group: string) {
getPostsByGroup(
@GetOrgFromRequest() org: Organization,
@Param('group') group: string
) {
return this._postsService.getPostsByGroup(org.id, group);
}

Expand Down
11 changes: 10 additions & 1 deletion apps/backend/src/api/routes/public.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { promisify } from 'util';
import { OnlyURL } from '@gitroom/nestjs-libraries/dtos/webhooks/webhooks.dto';
import { isSafePublicHttpsUrl } from '@gitroom/nestjs-libraries/dtos/webhooks/webhook.url.validator';
import { ssrfSafeDispatcher } from '@gitroom/nestjs-libraries/dtos/webhooks/ssrf.safe.dispatcher';
import { CreatePublicCommentDto } from '@gitroom/nestjs-libraries/dtos/comments/add.comment.dto';

const pump = promisify(pipeline);

Expand Down Expand Up @@ -76,6 +77,15 @@ export class PublicController {
return { comments: await this._postsService.getComments(postId) };
}

@Post(`/posts/:id/comments`)
async createComment(
@Param('id') postId: string,
@Body() body: CreatePublicCommentDto,
@RealIP() ip: string
) {
return this._postsService.createPublicComment(postId, body, null, ip);
}

@Post('/t')
async trackEvent(
@Res() res: Response,
Expand Down Expand Up @@ -154,7 +164,6 @@ export class PublicController {
}
}


@Get('/stream')
async streamFile(
@Query() query: OnlyURL,
Expand Down
2 changes: 1 addition & 1 deletion apps/frontend/src/app/(app)/(preview)/p/[id]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { PreviewWrapper } from '@gitroom/frontend/components/preview/preview.wra

export default async function AppLayout({ children }: { children: ReactNode }) {
return (
<div className="bg-[#000000] min-h-screen">
<div className="bg-newBgColor min-h-screen text-newTextColor">
<PreviewWrapper>{children}</PreviewWrapper>
</div>
);
Expand Down
185 changes: 91 additions & 94 deletions apps/frontend/src/app/(app)/(preview)/p/[id]/page.tsx

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions apps/frontend/src/app/(app)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export default async function AppLayout({ children }: { children: ReactNode }) {
googleAdsId={process.env.NEXT_PUBLIC_GTM_ID}
googleAdsTrialTracking={process.env.NEXT_PUBLIC_TRACKING_TRIAL}
language={language}
recaptchaSiteKey={process.env.RECAPTCHA_SITE_KEY || ''}
mediaProcessing={
process.env.STORAGE_PROVIDER === 'cloudflare' &&
!!process.env.RUNPOD_API_KEY &&
Expand Down
5 changes: 5 additions & 0 deletions apps/frontend/src/app/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -822,3 +822,8 @@ html[dir='rtl'] [dir='ltr'] {
text-shadow: -1px -1px 0 black, 1px -1px 0 black, -1px 1px 0 black,
1px 1px 0 black;
}

/* Preview page: text that can be selected to leave an inline comment */
.preview-comment-cursor {
cursor: url("data:image/svg+xml,%3Csvg xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22 width%3D%2228%22 height%3D%2228%22 viewBox%3D%220 0 28 28%22%3E%3Cg fill%3D%22none%22 stroke-linecap%3D%22round%22 stroke-linejoin%3D%22round%22%3E%3Cpath d%3D%22M3 4h6M3 24h6M6 4v20%22 stroke%3D%22%23fff%22 stroke-width%3D%224%22%2F%3E%3Cpath d%3D%22M3 4h6M3 24h6M6 4v20%22 stroke%3D%22%23000%22 stroke-width%3D%221.6%22%2F%3E%3Cpath d%3D%22M14 4h10a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2h-6l-4 3v-3a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z%22 fill%3D%22%23612bd3%22 stroke%3D%22%23fff%22 stroke-width%3D%221.5%22%2F%3E%3Cpath d%3D%22M17 8h6M17 11h4%22 stroke%3D%22%23fff%22 stroke-width%3D%221.5%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E") 6 14, text;
}
Loading
Loading