Skip to content

Commit e462993

Browse files
authored
Merge branch 'main' into chas/people-findings
2 parents 5d5a167 + 8785c18 commit e462993

199 files changed

Lines changed: 30787 additions & 3233 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,5 @@ scripts/sync-release-branch.sh
9595

9696
.claude/audit-findings.md
9797

98-
.superpowers/*
98+
.superpowers/*
99+
.claude/worktrees/

apps/api/package.json

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,57 @@
88
"@ai-sdk/groq": "^2.0.32",
99
"@ai-sdk/openai": "^2.0.65",
1010
"@aws-sdk/client-ec2": "^3.911.0",
11-
"@aws-sdk/client-s3": "^3.859.0",
11+
"@aws-sdk/client-s3": "3.1013.0",
12+
"@aws-sdk/client-acm": "^3.948.0",
13+
"@aws-sdk/client-backup": "^3.948.0",
14+
"@aws-sdk/client-cloudtrail": "^3.948.0",
15+
"@aws-sdk/client-cloudwatch": "^3.948.0",
16+
"@aws-sdk/client-cost-explorer": "^3.948.0",
17+
"@aws-sdk/client-cloudwatch-logs": "^3.948.0",
18+
"@aws-sdk/client-config-service": "^3.948.0",
19+
"@aws-sdk/client-dynamodb": "^3.948.0",
20+
"@aws-sdk/client-ecr": "^3.948.0",
21+
"@aws-sdk/client-ecs": "^3.948.0",
22+
"@aws-sdk/client-efs": "^3.948.0",
23+
"@aws-sdk/client-eks": "^3.948.0",
24+
"@aws-sdk/client-elastic-load-balancing-v2": "^3.948.0",
25+
"@aws-sdk/client-guardduty": "^3.948.0",
26+
"@aws-sdk/client-iam": "^3.948.0",
27+
"@aws-sdk/client-inspector2": "^3.948.0",
28+
"@aws-sdk/client-kms": "^3.948.0",
29+
"@aws-sdk/client-lambda": "^3.948.0",
30+
"@aws-sdk/client-macie2": "^3.948.0",
31+
"@aws-sdk/client-opensearch": "^3.948.0",
32+
"@aws-sdk/client-rds": "^3.948.0",
33+
"@aws-sdk/client-redshift": "^3.948.0",
34+
"@aws-sdk/client-route-53": "^3.948.0",
35+
"@aws-sdk/client-secrets-manager": "^3.948.0",
1236
"@aws-sdk/client-securityhub": "^3.948.0",
37+
"@aws-sdk/client-sns": "^3.948.0",
38+
"@aws-sdk/client-sqs": "^3.948.0",
39+
"@aws-sdk/client-wafv2": "^3.948.0",
40+
"@aws-sdk/client-api-gateway": "^3.948.0",
41+
"@aws-sdk/client-apigatewayv2": "^3.948.0",
42+
"@aws-sdk/client-appflow": "^3.948.0",
43+
"@aws-sdk/client-athena": "^3.948.0",
44+
"@aws-sdk/client-cloudfront": "^3.948.0",
45+
"@aws-sdk/client-codebuild": "^3.948.0",
46+
"@aws-sdk/client-cognito-identity-provider": "^3.948.0",
47+
"@aws-sdk/client-elastic-beanstalk": "^3.948.0",
48+
"@aws-sdk/client-elasticache": "^3.948.0",
49+
"@aws-sdk/client-emr": "^3.948.0",
50+
"@aws-sdk/client-eventbridge": "^3.948.0",
51+
"@aws-sdk/client-glue": "^3.948.0",
52+
"@aws-sdk/client-kafka": "^3.948.0",
53+
"@aws-sdk/client-kinesis": "^3.948.0",
54+
"@aws-sdk/client-network-firewall": "^3.948.0",
55+
"@aws-sdk/client-sagemaker": "^3.948.0",
56+
"@aws-sdk/client-sfn": "^3.948.0",
57+
"@aws-sdk/client-shield": "^3.948.0",
58+
"@aws-sdk/client-ssm": "^3.948.0",
1359
"@aws-sdk/client-sts": "^3.948.0",
14-
"@aws-sdk/s3-request-presigner": "^3.859.0",
60+
"@aws-sdk/client-transfer": "^3.948.0",
61+
"@aws-sdk/s3-request-presigner": "3.1013.0",
1562
"@browserbasehq/sdk": "2.6.0",
1663
"@browserbasehq/stagehand": "^3.0.5",
1764
"@mendable/firecrawl-js": "^4.9.3",

apps/api/src/app/s3.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
11
import {
22
GetObjectCommand,
3+
PutObjectCommand,
34
S3Client,
45
type GetObjectCommandOutput,
56
} from '@aws-sdk/client-s3';
7+
import { getSignedUrl as _getSignedUrl } from '@aws-sdk/s3-request-presigner';
68
import { Logger } from '@nestjs/common';
79
import '../config/load-env';
810

11+
/**
12+
* Re-export getSignedUrl with a type workaround for duplicate @smithy/types.
13+
* Bun/Docker installs separate @smithy/types copies for @aws-sdk/client-s3
14+
* and @aws-sdk/s3-request-presigner even when pinned to the same version.
15+
* The runtime types are fully compatible — only the TypeScript class identity differs.
16+
*/
17+
export const getSignedUrl = _getSignedUrl as unknown as (
18+
client: S3Client,
19+
command: GetObjectCommand | PutObjectCommand,
20+
options?: { expiresIn?: number },
21+
) => Promise<string>;
22+
923
const logger = new Logger('S3');
1024

1125
const APP_AWS_REGION = process.env.APP_AWS_REGION;

apps/api/src/attachments/attachments.service.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
PutObjectCommand,
66
S3Client,
77
} from '@aws-sdk/client-s3';
8-
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
8+
import { getSignedUrl, s3Client } from '@/app/s3';
99
import { AttachmentEntityType, AttachmentType, db } from '@db';
1010
import {
1111
BadRequestException,
@@ -15,7 +15,6 @@ import {
1515
import { randomBytes } from 'crypto';
1616
import { AttachmentResponseDto } from '../tasks/dto/task-responses.dto';
1717
import { UploadAttachmentDto } from './upload-attachment.dto';
18-
import { s3Client } from '@/app/s3';
1918
import { validateFileContent } from '../utils/file-type-validation';
2019

2120
@Injectable()

apps/api/src/auth/auth-context.decorator.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ export const UserId = createParamDecorator(
7676
}
7777

7878
if (!userId) {
79+
// For service tokens: allow if no user context needed (return a system identifier)
80+
if (authType === 'service') {
81+
return 'system';
82+
}
7983
throw new Error(
8084
'User ID not found. Ensure HybridAuthGuard is applied and using session auth.',
8185
);

apps/api/src/auth/hybrid-auth.guard.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,21 @@ export class HybridAuthGuard implements CanActivate {
112112
request.isPlatformAdmin = false;
113113
request.userRoles = null;
114114

115+
// Service tokens can pass x-user-id to act on behalf of a user
116+
// Validate that the user exists and belongs to the organization
117+
const actingUserId = request.headers['x-user-id'] as string;
118+
if (actingUserId) {
119+
const member = await db.member.findFirst({
120+
where: { userId: actingUserId, organizationId },
121+
select: { userId: true },
122+
});
123+
if (member) {
124+
request.userId = actingUserId;
125+
} else {
126+
this.logger.warn(`Service token x-user-id "${actingUserId}" not found in org ${organizationId}`);
127+
}
128+
}
129+
115130
this.logger.log(
116131
`Service "${service.definition.name}" authenticated for org ${organizationId}`,
117132
);

apps/api/src/browserbase/browserbase.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
PutObjectCommand,
1111
S3Client,
1212
} from '@aws-sdk/client-s3';
13-
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
13+
import { getSignedUrl } from '@/app/s3';
1414

1515
const BROWSER_WIDTH = 1440;
1616
const BROWSER_HEIGHT = 900;

0 commit comments

Comments
 (0)