@stacksjs/cloud 0.58.47 → 0.58.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +15 -14
- package/src/cloud/ai.ts +94 -0
- package/src/cloud/aws-sdk-layer/nodejs/package-lock.json +386 -0
- package/src/cloud/aws-sdk-layer/nodejs/package.json +15 -0
- package/src/cloud/cache.ts +0 -0
- package/src/cloud/cdn.ts +374 -0
- package/src/cloud/cli.ts +45 -0
- package/src/cloud/compute.ts +80 -0
- package/src/cloud/dashboard.ts +85 -0
- package/src/cloud/database.ts +0 -0
- package/src/cloud/deployment.ts +41 -0
- package/src/cloud/dns.ts +34 -0
- package/src/cloud/docs.ts +51 -0
- package/src/cloud/email.ts +339 -0
- package/src/cloud/file-system.ts +35 -0
- package/src/cloud/index.ts +99 -0
- package/src/cloud/jump-box.ts +48 -0
- package/src/cloud/lambda/ask/index.js +35 -0
- package/src/cloud/lambda/cli-setup/index.js +67 -0
- package/src/cloud/lambda/summarize/index.js +35 -0
- package/src/cloud/network.ts +52 -0
- package/src/cloud/package/README.md +59 -0
- package/src/cloud/package/package.json +63 -0
- package/src/cloud/permissions.ts +33 -0
- package/src/cloud/queue.ts +0 -0
- package/src/cloud/redirects.ts +45 -0
- package/src/cloud/router-layer/nodejs/package.json +15 -0
- package/src/cloud/search-engine.ts +108 -0
- package/src/cloud/security.ts +259 -0
- package/src/cloud/stacksjs-router-0.58.48.tgz +0 -0
- package/src/cloud/storage.ts +168 -0
- package/src/edge/origin-request.ts +49 -0
- package/src/helpers.ts +597 -0
- package/src/index.ts +3 -0
- package/src/runtime/README.md +116 -0
- package/src/runtime/bootstrap +3 -0
- package/src/runtime/example/lambda.ts +36 -0
- package/src/runtime/runtime.ts +830 -0
- package/src/runtime/scripts/build-layer.ts +104 -0
- package/src/runtime/scripts/publish-layer.ts +110 -0
- package/src/runtime/server.ts +39 -0
- package/src/types.ts +28 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import type { aws_kms as kms } from 'aws-cdk-lib'
|
|
2
|
+
import { RemovalPolicy, Tags, aws_backup as backup, aws_iam as iam, aws_s3 as s3 } from 'aws-cdk-lib'
|
|
3
|
+
import type { Construct } from 'constructs'
|
|
4
|
+
import type { NestedCloudProps } from '../types'
|
|
5
|
+
|
|
6
|
+
export interface StorageStackProps extends NestedCloudProps {
|
|
7
|
+
kmsKey: kms.Key
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class StorageStack {
|
|
11
|
+
publicBucket: s3.Bucket
|
|
12
|
+
privateBucket: s3.Bucket
|
|
13
|
+
logBucket: s3.Bucket
|
|
14
|
+
bucketPrefix: string
|
|
15
|
+
vault: backup.BackupVault
|
|
16
|
+
backupPlan: backup.BackupPlan
|
|
17
|
+
backupRole: iam.Role
|
|
18
|
+
|
|
19
|
+
constructor(scope: Construct, props: StorageStackProps) {
|
|
20
|
+
this.bucketPrefix = `${props.slug}-${props.appEnv}`
|
|
21
|
+
|
|
22
|
+
this.publicBucket = new s3.Bucket(scope, 'PublicBucket', {
|
|
23
|
+
bucketName: `${this.bucketPrefix}-public-${props.timestamp}`,
|
|
24
|
+
versioned: true,
|
|
25
|
+
autoDeleteObjects: true,
|
|
26
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
|
27
|
+
encryption: s3.BucketEncryption.S3_MANAGED,
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
Tags.of(this.publicBucket).add('daily-backup', 'true')
|
|
31
|
+
|
|
32
|
+
this.privateBucket = new s3.Bucket(scope, 'PrivateBucket', {
|
|
33
|
+
bucketName: `${this.bucketPrefix}-private-${props.timestamp}`,
|
|
34
|
+
versioned: true,
|
|
35
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
|
36
|
+
autoDeleteObjects: true,
|
|
37
|
+
encryption: s3.BucketEncryption.S3_MANAGED,
|
|
38
|
+
enforceSSL: true,
|
|
39
|
+
publicReadAccess: false,
|
|
40
|
+
blockPublicAccess: {
|
|
41
|
+
blockPublicAcls: true,
|
|
42
|
+
blockPublicPolicy: true,
|
|
43
|
+
ignorePublicAcls: true,
|
|
44
|
+
restrictPublicBuckets: true,
|
|
45
|
+
},
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
Tags.of(this.privateBucket).add('daily-backup', 'true')
|
|
49
|
+
|
|
50
|
+
this.logBucket = new s3.Bucket(scope, 'LogsBucket', {
|
|
51
|
+
bucketName: `${this.bucketPrefix}-logs-${props.timestamp}`,
|
|
52
|
+
removalPolicy: RemovalPolicy.RETAIN, // somehow, if we try to auto-delete logs, it fails bc the bucket is not empty (even though objects should be deleted) -> that's why we let buddy cloud:cleanup handle this which is auto triggered when buddy undeploy is ran
|
|
53
|
+
// autoDeleteObjects: true,
|
|
54
|
+
blockPublicAccess: new s3.BlockPublicAccess({
|
|
55
|
+
blockPublicAcls: false,
|
|
56
|
+
ignorePublicAcls: true,
|
|
57
|
+
blockPublicPolicy: true,
|
|
58
|
+
restrictPublicBuckets: true,
|
|
59
|
+
}),
|
|
60
|
+
objectOwnership: s3.ObjectOwnership.BUCKET_OWNER_PREFERRED,
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
Tags.of(this.logBucket).add('daily-backup', 'true')
|
|
64
|
+
|
|
65
|
+
this.backupRole = this.createBackupRole(scope)
|
|
66
|
+
|
|
67
|
+
// Daily 35 day retention
|
|
68
|
+
this.vault = new backup.BackupVault(scope, 'BackupVault', {
|
|
69
|
+
backupVaultName: `${props.slug}-${props.appEnv}-daily-backup-vault`,
|
|
70
|
+
encryptionKey: props.kmsKey,
|
|
71
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
this.backupPlan = backup.BackupPlan.daily35DayRetention(scope, 'BackupPlan', this.vault)
|
|
75
|
+
|
|
76
|
+
this.backupPlan.addSelection('Selection', {
|
|
77
|
+
role: this.backupRole,
|
|
78
|
+
resources: [backup.BackupResource.fromTag('daily-backup', 'true')],
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
createBackupRole(scope: Construct) {
|
|
83
|
+
const backupRole = new iam.Role(scope, 'BackupRole', {
|
|
84
|
+
assumedBy: new iam.ServicePrincipal('backup.amazonaws.com'),
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
backupRole.addToPolicy(
|
|
88
|
+
new iam.PolicyStatement({
|
|
89
|
+
actions: [
|
|
90
|
+
's3:GetInventoryConfiguration',
|
|
91
|
+
's3:PutInventoryConfiguration',
|
|
92
|
+
's3:ListBucketVersions',
|
|
93
|
+
's3:ListBucket',
|
|
94
|
+
's3:GetBucketVersioning',
|
|
95
|
+
's3:GetBucketNotification',
|
|
96
|
+
's3:PutBucketNotification',
|
|
97
|
+
's3:GetBucketLocation',
|
|
98
|
+
's3:GetBucketTagging',
|
|
99
|
+
],
|
|
100
|
+
resources: ['arn:aws:s3:::*'],
|
|
101
|
+
sid: 'S3BucketBackupPermissions',
|
|
102
|
+
}),
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
backupRole.addToPolicy(
|
|
106
|
+
new iam.PolicyStatement({
|
|
107
|
+
actions: [
|
|
108
|
+
's3:GetObjectAcl',
|
|
109
|
+
's3:GetObject',
|
|
110
|
+
's3:GetObjectVersionTagging',
|
|
111
|
+
's3:GetObjectVersionAcl',
|
|
112
|
+
's3:GetObjectTagging',
|
|
113
|
+
's3:GetObjectVersion',
|
|
114
|
+
],
|
|
115
|
+
resources: ['arn:aws:s3:::*/*'],
|
|
116
|
+
sid: 'S3ObjectBackupPermissions',
|
|
117
|
+
}),
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
backupRole.addToPolicy(
|
|
121
|
+
new iam.PolicyStatement({
|
|
122
|
+
actions: ['s3:ListAllMyBuckets'],
|
|
123
|
+
resources: ['*'],
|
|
124
|
+
sid: 'S3GlobalPermissions',
|
|
125
|
+
}),
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
backupRole.addToPolicy(
|
|
129
|
+
new iam.PolicyStatement({
|
|
130
|
+
actions: ['kms:Decrypt', 'kms:DescribeKey'],
|
|
131
|
+
resources: ['*'],
|
|
132
|
+
sid: 'KMSBackupPermissions',
|
|
133
|
+
conditions: {
|
|
134
|
+
StringLike: {
|
|
135
|
+
'kms:ViaService': 's3.*.amazonaws.com',
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
}),
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
backupRole.addToPolicy(
|
|
142
|
+
new iam.PolicyStatement({
|
|
143
|
+
actions: [
|
|
144
|
+
'events:DescribeRule',
|
|
145
|
+
'events:EnableRule',
|
|
146
|
+
'events:PutRule',
|
|
147
|
+
'events:DeleteRule',
|
|
148
|
+
'events:PutTargets',
|
|
149
|
+
'events:RemoveTargets',
|
|
150
|
+
'events:ListTargetsByRule',
|
|
151
|
+
'events:DisableRule',
|
|
152
|
+
],
|
|
153
|
+
resources: ['arn:aws:events:*:*:rule/AwsBackupManagedRule*'],
|
|
154
|
+
sid: 'EventsPermissions',
|
|
155
|
+
}),
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
backupRole.addToPolicy(
|
|
159
|
+
new iam.PolicyStatement({
|
|
160
|
+
actions: ['cloudwatch:GetMetricData', 'events:ListRules'],
|
|
161
|
+
resources: ['*'],
|
|
162
|
+
sid: 'EventsMetricsGlobalPermissions',
|
|
163
|
+
}),
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
return backupRole
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const config = {
|
|
2
|
+
suffix: '.html',
|
|
3
|
+
appendToDirs: 'index.html',
|
|
4
|
+
removeTrailingSlash: false,
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const regexSuffixless = /\/[^/.]+$/ // e.g. "/some/page" but not "/", "/some/" or "/some.jpg"
|
|
8
|
+
const regexTrailingSlash = /.+\/$/ // e.g. "/some/" or "/some/page/" but not root "/"
|
|
9
|
+
|
|
10
|
+
export function handler(event, context, callback) {
|
|
11
|
+
const { request } = event.Records[0].cf
|
|
12
|
+
const { uri } = request
|
|
13
|
+
const { suffix, appendToDirs } = config
|
|
14
|
+
|
|
15
|
+
// Append ".html" to origin request
|
|
16
|
+
if (suffix && uri.match(regexSuffixless)) {
|
|
17
|
+
request.uri = uri + suffix
|
|
18
|
+
callback(null, request)
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Append "index.html" to origin request
|
|
23
|
+
if (appendToDirs && uri.match(regexTrailingSlash)) {
|
|
24
|
+
request.uri = uri + appendToDirs
|
|
25
|
+
callback(null, request)
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Redirect (301) non-root requests ending in "/" to URI without trailing slash
|
|
30
|
+
// if (removeTrailingSlash && uri.match(/.+\/$/)) {
|
|
31
|
+
// const response = {
|
|
32
|
+
// // body: '',
|
|
33
|
+
// // bodyEncoding: 'text',
|
|
34
|
+
// headers: {
|
|
35
|
+
// location: [{
|
|
36
|
+
// key: 'Location',
|
|
37
|
+
// value: uri.slice(0, -1),
|
|
38
|
+
// }],
|
|
39
|
+
// },
|
|
40
|
+
// status: '301',
|
|
41
|
+
// statusDescription: 'Moved Permanently',
|
|
42
|
+
// }
|
|
43
|
+
// callback(null, response)
|
|
44
|
+
// return
|
|
45
|
+
// }
|
|
46
|
+
|
|
47
|
+
// If nothing matches, return request unchanged
|
|
48
|
+
callback(null, request)
|
|
49
|
+
}
|