mirror of
https://github.com/nestriness/nestri.git
synced 2025-12-12 08:45:38 +02:00
## Description <!-- Briefly describe the purpose and scope of your changes --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced serverless API and authentication endpoints, improving scalability and reliability. - Added rate limiting to the API, providing protection against excessive requests and returning custom error responses. - **Improvements** - Simplified infrastructure for both API and authentication, reducing complexity and improving maintainability. - Updated resource allocations for backend services to optimize performance and cost. - **Bug Fixes** - Removed unused scripts and configuration, resulting in a cleaner development environment. - **Other** - Updated type declarations to reflect new infrastructure changes. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
111 lines
3.2 KiB
TypeScript
111 lines
3.2 KiB
TypeScript
import { bus } from "./bus";
|
|
import { vpc } from "./vpc";
|
|
import { auth } from "./auth";
|
|
import { domain } from "./dns";
|
|
import { secret } from "./secret";
|
|
import { postgres } from "./postgres";
|
|
|
|
const apiFn = new sst.aws.Function("ApiFn", {
|
|
vpc,
|
|
handler: "packages/functions/src/api/index.handler",
|
|
streaming: !$dev,
|
|
link: [
|
|
bus,
|
|
auth,
|
|
postgres,
|
|
secret.SteamApiKey,
|
|
secret.PolarSecret,
|
|
secret.PolarWebhookSecret,
|
|
secret.NestriFamilyMonthly,
|
|
secret.NestriFamilyYearly,
|
|
secret.NestriFreeMonthly,
|
|
secret.NestriProMonthly,
|
|
secret.NestriProYearly,
|
|
],
|
|
url: true,
|
|
});
|
|
|
|
const provider = new aws.Provider("UsEast1", { region: "us-east-1" });
|
|
|
|
const webAcl = new aws.wafv2.WebAcl(
|
|
"ApiWaf",
|
|
{
|
|
scope: "CLOUDFRONT",
|
|
defaultAction: {
|
|
allow: {},
|
|
},
|
|
visibilityConfig: {
|
|
cloudwatchMetricsEnabled: true,
|
|
metricName: "api-rate-limit-metric",
|
|
sampledRequestsEnabled: true,
|
|
},
|
|
rules: [
|
|
{
|
|
name: "rate-limit-rule",
|
|
priority: 1,
|
|
action: {
|
|
block: {
|
|
customResponse: {
|
|
responseCode: 429,
|
|
customResponseBodyKey: "rate-limit-response",
|
|
},
|
|
},
|
|
},
|
|
statement: {
|
|
rateBasedStatement: {
|
|
limit: 2 * 60, // 2 rps per authorization header
|
|
evaluationWindowSec: 60,
|
|
aggregateKeyType: "CUSTOM_KEYS",
|
|
customKeys: [
|
|
{
|
|
header: {
|
|
name: "Authorization",
|
|
textTransformations: [{ priority: 0, type: "NONE" }],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
visibilityConfig: {
|
|
cloudwatchMetricsEnabled: true,
|
|
metricName: "rate-limit-rule-metric",
|
|
sampledRequestsEnabled: true,
|
|
},
|
|
},
|
|
],
|
|
customResponseBodies: [
|
|
{
|
|
key: "rate-limit-response",
|
|
content: JSON.stringify({
|
|
type: "rate_limit",
|
|
code: "too_many_requests",
|
|
message: "Rate limit exceeded. Please try again later.",
|
|
}),
|
|
contentType: "APPLICATION_JSON",
|
|
},
|
|
],
|
|
},
|
|
{ provider },
|
|
);
|
|
|
|
export const api = new sst.aws.Router("Api", {
|
|
routes: {
|
|
"/*": apiFn.url,
|
|
},
|
|
domain: {
|
|
name: "api." + domain,
|
|
dns: sst.cloudflare.dns(),
|
|
},
|
|
transform: {
|
|
cdn(args) {
|
|
if (!args.transform) {
|
|
args.transform = {
|
|
distribution: {},
|
|
};
|
|
}
|
|
args.transform!.distribution = {
|
|
webAclId: webAcl.arn,
|
|
};
|
|
},
|
|
},
|
|
}); |