insforge 1.2.10 → 1.3.0
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/.claude-plugin/marketplace.json +20 -20
- package/.dockerignore +60 -60
- package/.env.example +83 -77
- package/.github/ISSUE_TEMPLATE/bug_report.yml +36 -36
- package/.github/ISSUE_TEMPLATE/config.yml +11 -11
- package/.github/ISSUE_TEMPLATE/feature_request.yml +26 -26
- package/.github/PULL_REQUEST_TEMPLATE.md +7 -7
- package/.github/copilot-instructions.md +146 -146
- package/.github/workflows/build-image.yml +65 -65
- package/.github/workflows/ci-premerge-check.yml +23 -23
- package/.github/workflows/e2e.yml +63 -63
- package/.github/workflows/lint-and-format.yml +32 -32
- package/.prettierignore +64 -64
- package/CHANGELOG.md +44 -44
- package/CLAUDE_PLUGIN.md +104 -104
- package/CODE_OF_CONDUCT.md +128 -128
- package/CONTRIBUTING.md +125 -125
- package/Dockerfile +30 -30
- package/GITHUB_OAUTH_SETUP.md +49 -49
- package/GOOGLE_OAUTH_SETUP.md +148 -148
- package/LICENSE +201 -201
- package/README.md +182 -182
- package/assets/Dark.svg +23 -23
- package/auth/package.json +28 -28
- package/auth/src/lib/broadcastService.ts +117 -115
- package/auth/src/pages/SignInPage.tsx +60 -57
- package/auth/src/pages/SignUpPage.tsx +60 -57
- package/auth/tsconfig.json +32 -32
- package/auth/tsconfig.node.json +11 -11
- package/backend/package.json +78 -75
- package/backend/src/api/routes/ai/index.routes.ts +3 -3
- package/backend/src/api/routes/auth/index.routes.ts +667 -570
- package/backend/src/api/routes/auth/oauth.routes.ts +473 -448
- package/backend/src/api/routes/database/advance.routes.ts +37 -16
- package/backend/src/api/routes/database/index.routes.ts +78 -1
- package/backend/src/api/routes/database/records.routes.ts +10 -10
- package/backend/src/api/routes/database/tables.routes.ts +0 -14
- package/backend/src/api/routes/docs/index.routes.ts +75 -76
- package/backend/src/api/routes/email/index.routes.ts +35 -0
- package/backend/src/api/routes/functions/index.routes.ts +18 -12
- package/backend/src/api/routes/metadata/index.routes.ts +12 -0
- package/backend/src/api/routes/realtime/channels.routes.ts +81 -0
- package/backend/src/api/routes/realtime/index.routes.ts +12 -0
- package/backend/src/api/routes/realtime/messages.routes.ts +48 -0
- package/backend/src/api/routes/realtime/permissions.routes.ts +19 -0
- package/backend/src/api/routes/storage/index.routes.ts +18 -12
- package/backend/src/api/routes/usage/index.routes.ts +6 -4
- package/backend/src/infra/database/database.manager.ts +14 -1
- package/backend/src/infra/database/migrations/000_create-base-tables.sql +141 -141
- package/backend/src/infra/database/migrations/001_create-helper-functions.sql +40 -40
- package/backend/src/infra/database/migrations/002_rename-auth-tables.sql +29 -29
- package/backend/src/infra/database/migrations/003_create-users-table.sql +55 -55
- package/backend/src/infra/database/migrations/004_add-reload-postgrest-func.sql +23 -23
- package/backend/src/infra/database/migrations/005_enable-project-admin-modify-users.sql +29 -29
- package/backend/src/infra/database/migrations/006_modify-ai-usage-table.sql +24 -24
- package/backend/src/infra/database/migrations/007_drop-metadata-table.sql +1 -1
- package/backend/src/infra/database/migrations/008_add-system-tables.sql +76 -76
- package/backend/src/infra/database/migrations/009_add-function-secrets.sql +23 -23
- package/backend/src/infra/database/migrations/010_modify-ai-config-modalities.sql +93 -93
- package/backend/src/infra/database/migrations/011_refactor-secrets-table.sql +15 -15
- package/backend/src/infra/database/migrations/012_add-storage-uploaded-by.sql +7 -7
- package/backend/src/infra/database/migrations/013_create-auth-schema-functions.sql +44 -44
- package/backend/src/infra/database/migrations/014_add-updated-at-trigger-user-table.sql +7 -7
- package/backend/src/infra/database/migrations/015_create-auth-config-and-email-otp-tables.sql +59 -59
- package/backend/src/infra/database/migrations/016_update-auth-config-and-email-otp.sql +24 -24
- package/backend/src/infra/database/migrations/017_create-realtime-schema.sql +233 -0
- package/backend/src/infra/realtime/realtime.manager.ts +246 -0
- package/backend/src/infra/realtime/webhook-sender.ts +82 -0
- package/backend/src/infra/security/token.manager.ts +219 -125
- package/backend/src/infra/socket/socket.manager.ts +198 -64
- package/backend/src/providers/ai/openrouter.provider.ts +12 -9
- package/backend/src/providers/email/base.provider.ts +4 -7
- package/backend/src/providers/email/cloud.provider.ts +84 -0
- package/backend/src/providers/oauth/apple.provider.ts +266 -0
- package/backend/src/providers/oauth/index.ts +1 -0
- package/backend/src/server.ts +317 -284
- package/backend/src/services/ai/ai-model.service.ts +5 -5
- package/backend/src/services/ai/chat-completion.service.ts +4 -4
- package/backend/src/services/ai/image-generation.service.ts +3 -3
- package/backend/src/services/auth/auth.service.ts +14 -0
- package/backend/src/services/database/database-table.service.ts +0 -9
- package/backend/src/services/database/database.service.ts +127 -0
- package/backend/src/services/email/email.service.ts +5 -7
- package/backend/src/services/realtime/index.ts +3 -0
- package/backend/src/services/realtime/realtime-auth.service.ts +104 -0
- package/backend/src/services/realtime/realtime-channel.service.ts +237 -0
- package/backend/src/services/realtime/realtime-message.service.ts +260 -0
- package/backend/src/types/auth.ts +11 -0
- package/backend/src/types/realtime.ts +18 -0
- package/backend/src/types/socket.ts +7 -31
- package/backend/src/utils/cookies.ts +35 -0
- package/backend/src/utils/s3-config-loader.ts +64 -0
- package/backend/src/utils/seed.ts +301 -298
- package/backend/src/utils/sql-parser.ts +90 -0
- package/backend/tests/README.md +133 -133
- package/backend/tests/cleanup-all-test-data.sh +230 -230
- package/backend/tests/cloud/test-s3-multitenant.sh +131 -131
- package/backend/tests/local/comprehensive-curl-tests.sh +155 -155
- package/backend/tests/local/test-ai-config.sh +129 -129
- package/backend/tests/local/test-ai-usage.sh +80 -80
- package/backend/tests/local/test-auth-router.sh +143 -143
- package/backend/tests/local/test-database-router.sh +222 -222
- package/backend/tests/local/test-e2e.sh +240 -240
- package/backend/tests/local/test-fk-errors.sh +96 -96
- package/backend/tests/local/test-functions.sh +123 -123
- package/backend/tests/local/test-id-field.sh +200 -200
- package/backend/tests/local/test-logs.sh +132 -132
- package/backend/tests/local/test-public-bucket.sh +264 -264
- package/backend/tests/local/test-secrets.sh +249 -249
- package/backend/tests/local/test-serverless-functions.sh.disabled +325 -325
- package/backend/tests/local/test-traditional-rest.sh +208 -208
- package/backend/tests/manual/README.md +50 -50
- package/backend/tests/manual/create-large-table-simple.sql +10 -10
- package/backend/tests/manual/seed-large-table.sql +100 -100
- package/backend/tests/manual/setup-large-table-extras.sql +33 -33
- package/backend/tests/manual/test-bulk-upsert.sh +409 -409
- package/backend/tests/manual/test-database-advance.sh +296 -296
- package/backend/tests/manual/test-postgrest-stability.sh +191 -191
- package/backend/tests/manual/test-rawsql-export-import.sh +411 -411
- package/backend/tests/manual/test-rawsql-modes.sh +244 -244
- package/backend/tests/manual/test-universal-storage.sh +263 -263
- package/backend/tests/manual/test-users.sql +17 -17
- package/backend/tests/run-all-tests.sh +139 -139
- package/backend/tests/setup.ts +0 -0
- package/backend/tests/test-config.sh +338 -338
- package/backend/tests/unit/analyze-query.test.ts +697 -0
- package/backend/tsconfig.json +22 -22
- package/claude-plugin/.claude-plugin/plugin.json +24 -24
- package/claude-plugin/README.md +133 -133
- package/claude-plugin/skills/insforge-schema-patterns/SKILL.md +270 -270
- package/docker-compose.prod.yml +204 -200
- package/docker-compose.yml +232 -228
- package/docker-init/db/db-init.sql +97 -97
- package/docker-init/db/jwt.sql +5 -5
- package/docker-init/db/postgresql.conf +16 -16
- package/docker-init/logs/vector.yml +236 -236
- package/docs/README.md +44 -44
- package/docs/agent-docs/real-time.md +269 -0
- package/docs/changelog.mdx +119 -67
- package/docs/core-concepts/ai/architecture.mdx +372 -372
- package/docs/core-concepts/ai/sdk.mdx +213 -213
- package/docs/core-concepts/authentication/architecture.mdx +278 -278
- package/docs/core-concepts/authentication/sdk.mdx +414 -414
- package/docs/core-concepts/authentication/ui-components/customization.mdx +529 -529
- package/docs/core-concepts/authentication/ui-components/nextjs.mdx +221 -221
- package/docs/core-concepts/authentication/ui-components/react-router.mdx +184 -184
- package/docs/core-concepts/authentication/ui-components/react.mdx +129 -129
- package/docs/core-concepts/database/architecture.mdx +255 -255
- package/docs/core-concepts/database/sdk.mdx +382 -382
- package/docs/core-concepts/email/architecture.mdx +101 -0
- package/docs/core-concepts/email/sdk.mdx +53 -0
- package/docs/core-concepts/functions/architecture.mdx +105 -105
- package/docs/core-concepts/functions/sdk.mdx +184 -184
- package/docs/core-concepts/realtime/architecture.mdx +446 -0
- package/docs/core-concepts/realtime/sdk.mdx +409 -0
- package/docs/core-concepts/storage/architecture.mdx +243 -243
- package/docs/core-concepts/storage/sdk.mdx +253 -253
- package/docs/deployment/README.md +94 -94
- package/docs/deployment/deploy-to-aws-ec2.md +564 -564
- package/docs/deployment/deploy-to-azure-virtual-machines.md +312 -312
- package/docs/deployment/deploy-to-google-cloud-compute-engine.md +613 -613
- package/docs/deployment/deploy-to-render.md +441 -441
- package/docs/deprecated/insforge-auth-api.md +214 -214
- package/docs/deprecated/insforge-auth-sdk.md +99 -99
- package/docs/deprecated/insforge-db-api.md +358 -358
- package/docs/deprecated/insforge-db-sdk.md +139 -139
- package/docs/deprecated/insforge-debug-sdk.md +156 -156
- package/docs/deprecated/insforge-debug.md +64 -64
- package/docs/deprecated/insforge-instructions.md +123 -123
- package/docs/deprecated/insforge-project.md +117 -117
- package/docs/deprecated/insforge-storage-api.md +278 -278
- package/docs/deprecated/insforge-storage-sdk.md +158 -158
- package/docs/docs.json +232 -210
- package/docs/examples/framework-guides/nextjs.mdx +131 -131
- package/docs/examples/framework-guides/nuxt.mdx +165 -165
- package/docs/examples/framework-guides/react.mdx +165 -165
- package/docs/examples/framework-guides/svelte.mdx +153 -153
- package/docs/examples/framework-guides/vue.mdx +159 -159
- package/docs/examples/overview.mdx +67 -67
- package/docs/favicon.svg +19 -19
- package/docs/images/changelog/dec-2025/ai-integration.png +0 -0
- package/docs/images/changelog/dec-2025/ai-models.webp +0 -0
- package/docs/images/changelog/dec-2025/alipay-payment.webp +0 -0
- package/docs/images/changelog/dec-2025/apple-login.jpg +0 -0
- package/docs/images/changelog/dec-2025/mcp-installer.png +0 -0
- package/docs/images/changelog/dec-2025/realtime-module.jpg +0 -0
- package/docs/images/icons/ai.svg +4 -4
- package/docs/images/logos/nextjs.svg +4 -4
- package/docs/images/logos/nuxt.svg +4 -4
- package/docs/images/logos/react.svg +5 -5
- package/docs/images/logos/svelte.svg +4 -4
- package/docs/images/logos/vue.svg +5 -5
- package/docs/insforge-instructions-sdk.md +89 -88
- package/docs/introduction.mdx +45 -45
- package/docs/logo/dark.svg +22 -22
- package/docs/logo/light.svg +20 -20
- package/docs/partnership.mdx +651 -646
- package/docs/quickstart.mdx +82 -82
- package/docs/showcase.mdx +52 -52
- package/docs/snippets/sdk-installation.mdx +21 -21
- package/docs/snippets/service-icons.mdx +27 -27
- package/examples/oauth/frontend-oauth-example.html +250 -250
- package/examples/response-examples.md +443 -443
- package/frontend/components.json +17 -17
- package/frontend/package.json +69 -69
- package/frontend/src/assets/icons/checkbox_checked.svg +6 -6
- package/frontend/src/assets/icons/checkbox_undetermined.svg +6 -6
- package/frontend/src/assets/icons/checked.svg +3 -3
- package/frontend/src/assets/icons/connected.svg +3 -3
- package/frontend/src/assets/icons/error.svg +3 -3
- package/frontend/src/assets/icons/loader.svg +9 -9
- package/frontend/src/assets/icons/pencil.svg +4 -4
- package/frontend/src/assets/icons/refresh.svg +4 -4
- package/frontend/src/assets/icons/step_active.svg +3 -3
- package/frontend/src/assets/icons/step_inactive.svg +11 -11
- package/frontend/src/assets/icons/warning.svg +3 -3
- package/frontend/src/assets/logos/apple.svg +3 -3
- package/frontend/src/assets/logos/claude_code.svg +3 -3
- package/frontend/src/assets/logos/cline.svg +6 -6
- package/frontend/src/assets/logos/cursor.svg +20 -20
- package/frontend/src/assets/logos/discord.svg +8 -8
- package/frontend/src/assets/logos/facebook.svg +3 -3
- package/frontend/src/assets/logos/gemini.svg +19 -19
- package/frontend/src/assets/logos/github.svg +5 -5
- package/frontend/src/assets/logos/google.svg +13 -13
- package/frontend/src/assets/logos/grok.svg +10 -10
- package/frontend/src/assets/logos/insforge_dark.svg +15 -15
- package/frontend/src/assets/logos/insforge_light.svg +15 -15
- package/frontend/src/assets/logos/instagram.svg +1 -1
- package/frontend/src/assets/logos/linkedin.svg +3 -3
- package/frontend/src/assets/logos/openai.svg +10 -10
- package/frontend/src/assets/logos/roo_code.svg +9 -9
- package/frontend/src/assets/logos/spotify.svg +16 -16
- package/frontend/src/assets/logos/tiktok.svg +5 -5
- package/frontend/src/assets/logos/trae.svg +3 -3
- package/frontend/src/assets/logos/windsurf.svg +10 -10
- package/frontend/src/assets/logos/x.svg +3 -3
- package/frontend/src/components/layout/AppHeader.tsx +9 -10
- package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +1 -0
- package/frontend/src/features/auth/components/UsersDataGrid.tsx +6 -0
- package/frontend/src/features/auth/helpers.tsx +8 -0
- package/frontend/src/features/auth/{page → pages}/UsersPage.tsx +0 -28
- package/frontend/src/features/database/components/SQLModal.tsx +75 -0
- package/frontend/src/features/database/components/TableForm.tsx +0 -4
- package/frontend/src/features/database/hooks/useDatabase.ts +66 -0
- package/frontend/src/features/database/hooks/useTables.ts +32 -28
- package/frontend/src/features/database/index.ts +1 -0
- package/frontend/src/features/database/{page → pages}/FunctionsPage.tsx +29 -37
- package/frontend/src/features/database/{page → pages}/IndexesPage.tsx +35 -47
- package/frontend/src/features/database/{page → pages}/PoliciesPage.tsx +43 -54
- package/frontend/src/features/database/{page → pages}/TablesPage.tsx +0 -42
- package/frontend/src/features/database/{page → pages}/TriggersPage.tsx +35 -47
- package/frontend/src/features/database/services/advance.service.ts +0 -26
- package/frontend/src/features/database/services/database.service.ts +55 -0
- package/frontend/src/features/database/services/table.service.ts +0 -6
- package/frontend/src/features/functions/{page → pages}/FunctionsPage.tsx +21 -44
- package/frontend/src/features/functions/{page → pages}/SecretsPage.tsx +11 -9
- package/frontend/src/features/logs/hooks/useMcpUsage.ts +13 -66
- package/frontend/src/features/realtime/components/ChannelRow.tsx +83 -0
- package/frontend/src/features/realtime/components/EditChannelModal.tsx +246 -0
- package/frontend/src/features/realtime/components/MessageRow.tsx +85 -0
- package/frontend/src/features/realtime/components/RealtimeEmptyState.tsx +30 -0
- package/frontend/src/features/realtime/hooks/useRealtime.ts +218 -0
- package/frontend/src/features/realtime/index.ts +11 -0
- package/frontend/src/features/realtime/pages/RealtimeChannelsPage.tsx +172 -0
- package/frontend/src/features/realtime/pages/RealtimeMessagesPage.tsx +211 -0
- package/frontend/src/features/realtime/pages/RealtimePermissionsPage.tsx +191 -0
- package/frontend/src/features/realtime/services/realtime.service.ts +107 -0
- package/frontend/src/features/storage/{page → pages}/StoragePage.tsx +1 -29
- package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +3 -3
- package/frontend/src/features/visualizer/{page → pages}/VisualizerPage.tsx +1 -35
- package/frontend/src/lib/contexts/SocketContext.tsx +119 -75
- package/frontend/src/lib/routing/AppRoutes.tsx +35 -20
- package/frontend/src/lib/utils/cloudMessaging.ts +1 -1
- package/frontend/src/lib/utils/menuItems.ts +24 -0
- package/frontend/src/lib/utils/utils.ts +14 -1
- package/frontend/tsconfig.json +25 -25
- package/frontend/tsconfig.node.json +9 -9
- package/functions/deno.json +24 -24
- package/functions/server.ts +315 -315
- package/i18n/README.ar.md +130 -130
- package/i18n/README.de.md +130 -130
- package/i18n/README.es.md +154 -154
- package/i18n/README.fr.md +134 -134
- package/i18n/README.hi.md +129 -129
- package/i18n/README.ja.md +174 -174
- package/i18n/README.ko.md +136 -136
- package/i18n/README.pt-BR.md +131 -131
- package/i18n/README.ru.md +129 -129
- package/i18n/README.zh-CN.md +133 -133
- package/openapi/ai.yaml +715 -715
- package/openapi/auth.yaml +1244 -1244
- package/openapi/email.yaml +158 -0
- package/openapi/functions.yaml +475 -475
- package/openapi/health.yaml +29 -29
- package/openapi/logs.yaml +223 -223
- package/openapi/metadata.yaml +177 -177
- package/openapi/realtime.yaml +699 -0
- package/openapi/records.yaml +381 -381
- package/openapi/secrets.yaml +370 -370
- package/openapi/storage.yaml +875 -875
- package/openapi/tables.yaml +463 -463
- package/package.json +97 -97
- package/shared-schemas/package.json +31 -31
- package/shared-schemas/src/ai.schema.ts +63 -59
- package/shared-schemas/src/auth-api.schema.ts +352 -339
- package/shared-schemas/src/auth.schema.ts +1 -1
- package/shared-schemas/src/database-api.schema.ts +32 -1
- package/shared-schemas/src/database.schema.ts +39 -0
- package/shared-schemas/src/docs.schema.ts +26 -0
- package/shared-schemas/src/email-api.schema.ts +30 -0
- package/shared-schemas/src/index.ts +4 -0
- package/shared-schemas/src/metadata.schema.ts +9 -0
- package/shared-schemas/src/realtime-api.schema.ts +111 -0
- package/shared-schemas/src/realtime.schema.ts +143 -0
- package/shared-schemas/tsconfig.json +21 -21
- package/tsconfig.json +7 -7
- package/zeabur/README.md +13 -13
- package/zeabur/template.yml +1032 -1032
- package/.cursor/rules/cursor-rules.mdc +0 -94
- package/frontend/src/features/database/hooks/useFullMetadata.ts +0 -18
- package/test-gemini.sh +0 -35
- package/test-usage-admin.sh +0 -57
- package/test-usage.sh +0 -50
- /package/frontend/src/features/ai/{page → pages}/AIPage.tsx +0 -0
- /package/frontend/src/features/auth/{page → pages}/AuthMethodsPage.tsx +0 -0
- /package/frontend/src/features/auth/{page → pages}/ConfigurationPage.tsx +0 -0
- /package/frontend/src/features/dashboard/{page → pages}/DashboardPage.tsx +0 -0
- /package/frontend/src/features/database/{page → pages}/SQLEditorPage.tsx +0 -0
- /package/frontend/src/features/database/{page → pages}/TemplatesPage.tsx +0 -0
- /package/frontend/src/features/login/{page → pages}/CloudLoginPage.tsx +0 -0
- /package/frontend/src/features/login/{page → pages}/LoginPage.tsx +0 -0
- /package/frontend/src/features/logs/{page → pages}/AuditsPage.tsx +0 -0
- /package/frontend/src/features/logs/{page → pages}/LogsPage.tsx +0 -0
- /package/frontend/src/features/logs/{page → pages}/MCPLogsPage.tsx +0 -0
|
@@ -1,265 +1,265 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# Get the directory where this script is located
|
|
4
|
-
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
5
|
-
|
|
6
|
-
# Source the test configuration
|
|
7
|
-
source "$SCRIPT_DIR/../test-config.sh"
|
|
8
|
-
|
|
9
|
-
# Configuration
|
|
10
|
-
API_BASE_URL="$TEST_API_BASE"
|
|
11
|
-
PUBLIC_BUCKET="public-images-$(date +%s)"
|
|
12
|
-
PRIVATE_BUCKET="private-docs-$(date +%s)"
|
|
13
|
-
TEST_FILE="test.txt"
|
|
14
|
-
|
|
15
|
-
# Register buckets for cleanup
|
|
16
|
-
register_test_bucket "$PUBLIC_BUCKET"
|
|
17
|
-
register_test_bucket "$PRIVATE_BUCKET"
|
|
18
|
-
|
|
19
|
-
echo "🧪 Testing Public/Private Bucket Functionality"
|
|
20
|
-
echo "============================================="
|
|
21
|
-
|
|
22
|
-
# Get admin token for auth endpoints
|
|
23
|
-
admin_token=$(get_admin_token)
|
|
24
|
-
if [ -z "$admin_token" ]; then
|
|
25
|
-
print_fail "Could not get admin token"
|
|
26
|
-
else
|
|
27
|
-
print_success "Admin authentication successful"
|
|
28
|
-
fi
|
|
29
|
-
|
|
30
|
-
# Get API key for storage operations
|
|
31
|
-
api_key=$(get_admin_api_key)
|
|
32
|
-
|
|
33
|
-
# If that fails, try to get it via the API endpoint
|
|
34
|
-
if [ -z "$api_key" ] && [ -n "$admin_token" ]; then
|
|
35
|
-
api_key_response=$(curl -s "$TEST_API_BASE/metadata/api-key" \
|
|
36
|
-
-H "Authorization: Bearer $admin_token")
|
|
37
|
-
api_key=$(echo "$api_key_response" | grep -o '"apiKey":"[^"]*' | cut -d'"' -f4)
|
|
38
|
-
fi
|
|
39
|
-
|
|
40
|
-
# Export for cleanup
|
|
41
|
-
if [ -n "$api_key" ]; then
|
|
42
|
-
export ACCESS_API_KEY="$api_key"
|
|
43
|
-
print_success "API key obtained for storage operations"
|
|
44
|
-
else
|
|
45
|
-
print_fail "Could not get API key for storage operations"
|
|
46
|
-
fi
|
|
47
|
-
|
|
48
|
-
# Step 1: Create a public bucket
|
|
49
|
-
print_info "1️⃣ Creating PUBLIC bucket: $PUBLIC_BUCKET"
|
|
50
|
-
response=$(curl -s -w "\n%{http_code}" -X POST "${API_BASE_URL}/storage/buckets" \
|
|
51
|
-
-H "Authorization: Bearer ${api_key}" \
|
|
52
|
-
-H "Content-Type: application/json" \
|
|
53
|
-
-d "{\"bucketName\": \"${PUBLIC_BUCKET}\", \"isPublic\": true}")
|
|
54
|
-
|
|
55
|
-
body=$(echo "$response" | sed '$d')
|
|
56
|
-
status=$(echo "$response" | tail -n 1)
|
|
57
|
-
|
|
58
|
-
if [ "$status" -ge 200 ] && [ "$status" -lt 300 ]; then
|
|
59
|
-
print_success "Public bucket created ($status)"
|
|
60
|
-
# Pretty print JSON if available
|
|
61
|
-
if command -v jq &> /dev/null && echo "$body" | jq . >/dev/null 2>&1; then
|
|
62
|
-
echo "$body" | jq '.'
|
|
63
|
-
else
|
|
64
|
-
echo "Response: $body"
|
|
65
|
-
fi
|
|
66
|
-
else
|
|
67
|
-
print_fail "Public bucket creation failed ($status)"
|
|
68
|
-
echo "Error: $body"
|
|
69
|
-
fi
|
|
70
|
-
|
|
71
|
-
# Step 2: Create a private bucket
|
|
72
|
-
print_info "2️⃣ Creating PRIVATE bucket: $PRIVATE_BUCKET"
|
|
73
|
-
response=$(curl -s -w "\n%{http_code}" -X POST "${API_BASE_URL}/storage/buckets" \
|
|
74
|
-
-H "Authorization: Bearer ${api_key}" \
|
|
75
|
-
-H "Content-Type: application/json" \
|
|
76
|
-
-d "{\"bucketName\": \"${PRIVATE_BUCKET}\", \"isPublic\": false}")
|
|
77
|
-
|
|
78
|
-
body=$(echo "$response" | sed '$d')
|
|
79
|
-
status=$(echo "$response" | tail -n 1)
|
|
80
|
-
|
|
81
|
-
if [ "$status" -ge 200 ] && [ "$status" -lt 300 ]; then
|
|
82
|
-
print_success "Private bucket created ($status)"
|
|
83
|
-
if command -v jq &> /dev/null && echo "$body" | jq . >/dev/null 2>&1; then
|
|
84
|
-
echo "$body" | jq '.'
|
|
85
|
-
else
|
|
86
|
-
echo "Response: $body"
|
|
87
|
-
fi
|
|
88
|
-
else
|
|
89
|
-
print_fail "Private bucket creation failed ($status)"
|
|
90
|
-
echo "Error: $body"
|
|
91
|
-
fi
|
|
92
|
-
|
|
93
|
-
# Step 3: Upload a test file to public bucket
|
|
94
|
-
print_info "3️⃣ Uploading file to PUBLIC bucket..."
|
|
95
|
-
# First delete if exists
|
|
96
|
-
curl -s -X DELETE "${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}/objects/${TEST_FILE}" \
|
|
97
|
-
-H "Authorization: Bearer ${api_key}" > /dev/null 2>&1
|
|
98
|
-
|
|
99
|
-
echo "This is a test file for public access" > /tmp/public-test.txt
|
|
100
|
-
response=$(curl -s -w "\n%{http_code}" -X PUT "${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}/objects/${TEST_FILE}" \
|
|
101
|
-
-H "Authorization: Bearer ${api_key}" \
|
|
102
|
-
-F "file=@/tmp/public-test.txt")
|
|
103
|
-
|
|
104
|
-
body=$(echo "$response" | sed '$d')
|
|
105
|
-
status=$(echo "$response" | tail -n 1)
|
|
106
|
-
|
|
107
|
-
if [ "$status" -ge 200 ] && [ "$status" -lt 300 ]; then
|
|
108
|
-
print_success "File uploaded to public bucket ($status)"
|
|
109
|
-
if command -v jq &> /dev/null && echo "$body" | jq . >/dev/null 2>&1; then
|
|
110
|
-
echo "$body" | jq '.'
|
|
111
|
-
else
|
|
112
|
-
echo "Response: $body"
|
|
113
|
-
fi
|
|
114
|
-
else
|
|
115
|
-
print_fail "File upload to public bucket failed ($status)"
|
|
116
|
-
echo "Error: $body"
|
|
117
|
-
fi
|
|
118
|
-
|
|
119
|
-
# Step 4: Upload a test file to private bucket
|
|
120
|
-
print_info "4️⃣ Uploading file to PRIVATE bucket..."
|
|
121
|
-
# First delete if exists
|
|
122
|
-
curl -s -X DELETE "${API_BASE_URL}/storage/buckets/${PRIVATE_BUCKET}/objects/${TEST_FILE}" \
|
|
123
|
-
-H "Authorization: Bearer ${api_key}" > /dev/null 2>&1
|
|
124
|
-
|
|
125
|
-
echo "This is a test file for private access" > /tmp/private-test.txt
|
|
126
|
-
response=$(curl -s -w "\n%{http_code}" -X PUT "${API_BASE_URL}/storage/buckets/${PRIVATE_BUCKET}/objects/${TEST_FILE}" \
|
|
127
|
-
-H "Authorization: Bearer ${api_key}" \
|
|
128
|
-
-F "file=@/tmp/private-test.txt")
|
|
129
|
-
|
|
130
|
-
body=$(echo "$response" | sed '$d')
|
|
131
|
-
status=$(echo "$response" | tail -n 1)
|
|
132
|
-
|
|
133
|
-
if [ "$status" -ge 200 ] && [ "$status" -lt 300 ]; then
|
|
134
|
-
print_success "File uploaded to private bucket ($status)"
|
|
135
|
-
if command -v jq &> /dev/null && echo "$body" | jq . >/dev/null 2>&1; then
|
|
136
|
-
echo "$body" | jq '.'
|
|
137
|
-
else
|
|
138
|
-
echo "Response: $body"
|
|
139
|
-
fi
|
|
140
|
-
else
|
|
141
|
-
print_fail "File upload to private bucket failed ($status)"
|
|
142
|
-
echo "Error: $body"
|
|
143
|
-
fi
|
|
144
|
-
|
|
145
|
-
# Step 5: Test accessing PUBLIC file WITHOUT API key
|
|
146
|
-
print_info "5️⃣ Testing PUBLIC file access WITHOUT API key..."
|
|
147
|
-
echo " Accessing: ${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}/objects/${TEST_FILE}"
|
|
148
|
-
HTTP_CODE=$(curl -s -L -o /tmp/public-response.txt -w "%{http_code}" "${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}/objects/${TEST_FILE}")
|
|
149
|
-
if [ "$HTTP_CODE" -eq 200 ]; then
|
|
150
|
-
print_success "Public file accessible without API key! (Status: ${HTTP_CODE})"
|
|
151
|
-
echo " 📄 Content: $(cat /tmp/public-response.txt)"
|
|
152
|
-
else
|
|
153
|
-
print_fail "Public file NOT accessible without API key (Status: ${HTTP_CODE})"
|
|
154
|
-
fi
|
|
155
|
-
|
|
156
|
-
# Step 6: Test accessing PRIVATE file WITHOUT API key
|
|
157
|
-
print_info "6️⃣ Testing PRIVATE file access WITHOUT API key..."
|
|
158
|
-
echo " Accessing: ${API_BASE_URL}/storage/buckets/${PRIVATE_BUCKET}/objects/${TEST_FILE}"
|
|
159
|
-
HTTP_CODE=$(curl -s -o /tmp/private-response.txt -w "%{http_code}" "${API_BASE_URL}/storage/buckets/${PRIVATE_BUCKET}/objects/${TEST_FILE}")
|
|
160
|
-
if [ "$HTTP_CODE" -eq 401 ]; then
|
|
161
|
-
print_success "Private file correctly blocked without API key! (Status: ${HTTP_CODE})"
|
|
162
|
-
else
|
|
163
|
-
print_fail "Private file should NOT be accessible without API key (Status: ${HTTP_CODE})"
|
|
164
|
-
fi
|
|
165
|
-
|
|
166
|
-
# Step 7: Test accessing PRIVATE file WITH API key
|
|
167
|
-
print_info "7️⃣ Testing PRIVATE file access WITH API key..."
|
|
168
|
-
HTTP_CODE=$(curl -s -L -o /tmp/private-auth-response.txt -w "%{http_code}" \
|
|
169
|
-
-H "Authorization: Bearer ${api_key}" \
|
|
170
|
-
"${API_BASE_URL}/storage/buckets/${PRIVATE_BUCKET}/objects/${TEST_FILE}")
|
|
171
|
-
if [ "$HTTP_CODE" -eq 200 ]; then
|
|
172
|
-
print_success "Private file accessible with API key! (Status: ${HTTP_CODE})"
|
|
173
|
-
echo " 📄 Content: $(cat /tmp/private-auth-response.txt)"
|
|
174
|
-
else
|
|
175
|
-
print_fail "Private file should be accessible with API key (Status: ${HTTP_CODE})"
|
|
176
|
-
fi
|
|
177
|
-
|
|
178
|
-
# Step 8: List all buckets
|
|
179
|
-
print_info "8️⃣ Listing all buckets..."
|
|
180
|
-
response=$(curl -s -w "\n%{http_code}" -H "Authorization: Bearer ${api_key}" "${API_BASE_URL}/storage/buckets")
|
|
181
|
-
body=$(echo "$response" | sed '$d')
|
|
182
|
-
status=$(echo "$response" | tail -n 1)
|
|
183
|
-
|
|
184
|
-
if [ "$status" -eq 200 ]; then
|
|
185
|
-
print_success "Buckets listed successfully"
|
|
186
|
-
if command -v jq &> /dev/null && echo "$body" | jq . >/dev/null 2>&1; then
|
|
187
|
-
echo "$body" | jq '.[] | "\(.name) - \(if .public then "🌍 PUBLIC" else "🔒 PRIVATE" end)"' -r 2>/dev/null || echo "Could not parse bucket list"
|
|
188
|
-
else
|
|
189
|
-
echo "Response: $body"
|
|
190
|
-
fi
|
|
191
|
-
else
|
|
192
|
-
print_fail "Failed to list buckets ($status)"
|
|
193
|
-
echo "Error: $body"
|
|
194
|
-
fi
|
|
195
|
-
|
|
196
|
-
# Step 9: Test POST upload with auto-generated key
|
|
197
|
-
print_info "9️⃣ Testing POST upload with auto-generated key..."
|
|
198
|
-
echo "This is a test file for POST upload" > /tmp/post-test.txt
|
|
199
|
-
response=$(curl -s -w "\n%{http_code}" -X POST "${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}/objects" \
|
|
200
|
-
-H "Authorization: Bearer ${api_key}" \
|
|
201
|
-
-F "file=@/tmp/post-test.txt")
|
|
202
|
-
|
|
203
|
-
body=$(echo "$response" | sed '$d')
|
|
204
|
-
status=$(echo "$response" | tail -n 1)
|
|
205
|
-
|
|
206
|
-
if [ "$status" -ge 200 ] && [ "$status" -lt 300 ]; then
|
|
207
|
-
print_success "File uploaded via POST with auto-generated key ($status)"
|
|
208
|
-
if command -v jq &> /dev/null && echo "$body" | jq . >/dev/null 2>&1; then
|
|
209
|
-
echo "$body" | jq '.'
|
|
210
|
-
# Extract the generated key for verification
|
|
211
|
-
generated_key=$(echo "$body" | jq -r '.key')
|
|
212
|
-
echo " 📝 Generated key: $generated_key"
|
|
213
|
-
# Test downloading the file with generated key
|
|
214
|
-
HTTP_CODE=$(curl -s -L -o /tmp/post-download.txt -w "%{http_code}" "${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}/objects/${generated_key}")
|
|
215
|
-
if [ "$HTTP_CODE" -eq 200 ]; then
|
|
216
|
-
print_success "Downloaded file with generated key!"
|
|
217
|
-
echo " 📄 Content: $(cat /tmp/post-download.txt)"
|
|
218
|
-
else
|
|
219
|
-
print_fail "Could not download file with generated key (Status: ${HTTP_CODE})"
|
|
220
|
-
fi
|
|
221
|
-
else
|
|
222
|
-
echo "Response: $body"
|
|
223
|
-
fi
|
|
224
|
-
else
|
|
225
|
-
print_fail "POST upload failed ($status)"
|
|
226
|
-
echo "Error: $body"
|
|
227
|
-
fi
|
|
228
|
-
|
|
229
|
-
# Step 10: Update bucket visibility
|
|
230
|
-
print_info "🔟 Testing bucket visibility update (making public bucket private)..."
|
|
231
|
-
response=$(curl -s -w "\n%{http_code}" -X PATCH "${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}" \
|
|
232
|
-
-H "Authorization: Bearer ${api_key}" \
|
|
233
|
-
-H "Content-Type: application/json" \
|
|
234
|
-
-d '{"isPublic": false}')
|
|
235
|
-
|
|
236
|
-
body=$(echo "$response" | sed '$d')
|
|
237
|
-
status=$(echo "$response" | tail -n 1)
|
|
238
|
-
|
|
239
|
-
if [ "$status" -ge 200 ] && [ "$status" -lt 300 ]; then
|
|
240
|
-
print_success "Bucket visibility updated ($status)"
|
|
241
|
-
if command -v jq &> /dev/null && echo "$body" | jq . >/dev/null 2>&1; then
|
|
242
|
-
echo "$body" | jq '.'
|
|
243
|
-
else
|
|
244
|
-
echo "Response: $body"
|
|
245
|
-
fi
|
|
246
|
-
else
|
|
247
|
-
print_fail "Bucket visibility update failed ($status)"
|
|
248
|
-
echo "Error: $body"
|
|
249
|
-
fi
|
|
250
|
-
|
|
251
|
-
# Test access again
|
|
252
|
-
echo " Testing access after update..."
|
|
253
|
-
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}/objects/${TEST_FILE}")
|
|
254
|
-
if [ "$HTTP_CODE" -eq 401 ]; then
|
|
255
|
-
print_success "Previously public file now requires authentication!"
|
|
256
|
-
else
|
|
257
|
-
print_fail "File should now require authentication (Status: ${HTTP_CODE})"
|
|
258
|
-
fi
|
|
259
|
-
|
|
260
|
-
# Cleanup temp files only
|
|
261
|
-
print_info "🧹 Cleaning up temp files..."
|
|
262
|
-
rm -f /tmp/public-test.txt /tmp/private-test.txt /tmp/public-response.txt /tmp/private-response.txt /tmp/private-auth-response.txt /tmp/post-test.txt /tmp/post-download.txt
|
|
263
|
-
|
|
264
|
-
print_success "✨ Public/Private bucket test completed!"
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Get the directory where this script is located
|
|
4
|
+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
5
|
+
|
|
6
|
+
# Source the test configuration
|
|
7
|
+
source "$SCRIPT_DIR/../test-config.sh"
|
|
8
|
+
|
|
9
|
+
# Configuration
|
|
10
|
+
API_BASE_URL="$TEST_API_BASE"
|
|
11
|
+
PUBLIC_BUCKET="public-images-$(date +%s)"
|
|
12
|
+
PRIVATE_BUCKET="private-docs-$(date +%s)"
|
|
13
|
+
TEST_FILE="test.txt"
|
|
14
|
+
|
|
15
|
+
# Register buckets for cleanup
|
|
16
|
+
register_test_bucket "$PUBLIC_BUCKET"
|
|
17
|
+
register_test_bucket "$PRIVATE_BUCKET"
|
|
18
|
+
|
|
19
|
+
echo "🧪 Testing Public/Private Bucket Functionality"
|
|
20
|
+
echo "============================================="
|
|
21
|
+
|
|
22
|
+
# Get admin token for auth endpoints
|
|
23
|
+
admin_token=$(get_admin_token)
|
|
24
|
+
if [ -z "$admin_token" ]; then
|
|
25
|
+
print_fail "Could not get admin token"
|
|
26
|
+
else
|
|
27
|
+
print_success "Admin authentication successful"
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
# Get API key for storage operations
|
|
31
|
+
api_key=$(get_admin_api_key)
|
|
32
|
+
|
|
33
|
+
# If that fails, try to get it via the API endpoint
|
|
34
|
+
if [ -z "$api_key" ] && [ -n "$admin_token" ]; then
|
|
35
|
+
api_key_response=$(curl -s "$TEST_API_BASE/metadata/api-key" \
|
|
36
|
+
-H "Authorization: Bearer $admin_token")
|
|
37
|
+
api_key=$(echo "$api_key_response" | grep -o '"apiKey":"[^"]*' | cut -d'"' -f4)
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
# Export for cleanup
|
|
41
|
+
if [ -n "$api_key" ]; then
|
|
42
|
+
export ACCESS_API_KEY="$api_key"
|
|
43
|
+
print_success "API key obtained for storage operations"
|
|
44
|
+
else
|
|
45
|
+
print_fail "Could not get API key for storage operations"
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# Step 1: Create a public bucket
|
|
49
|
+
print_info "1️⃣ Creating PUBLIC bucket: $PUBLIC_BUCKET"
|
|
50
|
+
response=$(curl -s -w "\n%{http_code}" -X POST "${API_BASE_URL}/storage/buckets" \
|
|
51
|
+
-H "Authorization: Bearer ${api_key}" \
|
|
52
|
+
-H "Content-Type: application/json" \
|
|
53
|
+
-d "{\"bucketName\": \"${PUBLIC_BUCKET}\", \"isPublic\": true}")
|
|
54
|
+
|
|
55
|
+
body=$(echo "$response" | sed '$d')
|
|
56
|
+
status=$(echo "$response" | tail -n 1)
|
|
57
|
+
|
|
58
|
+
if [ "$status" -ge 200 ] && [ "$status" -lt 300 ]; then
|
|
59
|
+
print_success "Public bucket created ($status)"
|
|
60
|
+
# Pretty print JSON if available
|
|
61
|
+
if command -v jq &> /dev/null && echo "$body" | jq . >/dev/null 2>&1; then
|
|
62
|
+
echo "$body" | jq '.'
|
|
63
|
+
else
|
|
64
|
+
echo "Response: $body"
|
|
65
|
+
fi
|
|
66
|
+
else
|
|
67
|
+
print_fail "Public bucket creation failed ($status)"
|
|
68
|
+
echo "Error: $body"
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
# Step 2: Create a private bucket
|
|
72
|
+
print_info "2️⃣ Creating PRIVATE bucket: $PRIVATE_BUCKET"
|
|
73
|
+
response=$(curl -s -w "\n%{http_code}" -X POST "${API_BASE_URL}/storage/buckets" \
|
|
74
|
+
-H "Authorization: Bearer ${api_key}" \
|
|
75
|
+
-H "Content-Type: application/json" \
|
|
76
|
+
-d "{\"bucketName\": \"${PRIVATE_BUCKET}\", \"isPublic\": false}")
|
|
77
|
+
|
|
78
|
+
body=$(echo "$response" | sed '$d')
|
|
79
|
+
status=$(echo "$response" | tail -n 1)
|
|
80
|
+
|
|
81
|
+
if [ "$status" -ge 200 ] && [ "$status" -lt 300 ]; then
|
|
82
|
+
print_success "Private bucket created ($status)"
|
|
83
|
+
if command -v jq &> /dev/null && echo "$body" | jq . >/dev/null 2>&1; then
|
|
84
|
+
echo "$body" | jq '.'
|
|
85
|
+
else
|
|
86
|
+
echo "Response: $body"
|
|
87
|
+
fi
|
|
88
|
+
else
|
|
89
|
+
print_fail "Private bucket creation failed ($status)"
|
|
90
|
+
echo "Error: $body"
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# Step 3: Upload a test file to public bucket
|
|
94
|
+
print_info "3️⃣ Uploading file to PUBLIC bucket..."
|
|
95
|
+
# First delete if exists
|
|
96
|
+
curl -s -X DELETE "${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}/objects/${TEST_FILE}" \
|
|
97
|
+
-H "Authorization: Bearer ${api_key}" > /dev/null 2>&1
|
|
98
|
+
|
|
99
|
+
echo "This is a test file for public access" > /tmp/public-test.txt
|
|
100
|
+
response=$(curl -s -w "\n%{http_code}" -X PUT "${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}/objects/${TEST_FILE}" \
|
|
101
|
+
-H "Authorization: Bearer ${api_key}" \
|
|
102
|
+
-F "file=@/tmp/public-test.txt")
|
|
103
|
+
|
|
104
|
+
body=$(echo "$response" | sed '$d')
|
|
105
|
+
status=$(echo "$response" | tail -n 1)
|
|
106
|
+
|
|
107
|
+
if [ "$status" -ge 200 ] && [ "$status" -lt 300 ]; then
|
|
108
|
+
print_success "File uploaded to public bucket ($status)"
|
|
109
|
+
if command -v jq &> /dev/null && echo "$body" | jq . >/dev/null 2>&1; then
|
|
110
|
+
echo "$body" | jq '.'
|
|
111
|
+
else
|
|
112
|
+
echo "Response: $body"
|
|
113
|
+
fi
|
|
114
|
+
else
|
|
115
|
+
print_fail "File upload to public bucket failed ($status)"
|
|
116
|
+
echo "Error: $body"
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
# Step 4: Upload a test file to private bucket
|
|
120
|
+
print_info "4️⃣ Uploading file to PRIVATE bucket..."
|
|
121
|
+
# First delete if exists
|
|
122
|
+
curl -s -X DELETE "${API_BASE_URL}/storage/buckets/${PRIVATE_BUCKET}/objects/${TEST_FILE}" \
|
|
123
|
+
-H "Authorization: Bearer ${api_key}" > /dev/null 2>&1
|
|
124
|
+
|
|
125
|
+
echo "This is a test file for private access" > /tmp/private-test.txt
|
|
126
|
+
response=$(curl -s -w "\n%{http_code}" -X PUT "${API_BASE_URL}/storage/buckets/${PRIVATE_BUCKET}/objects/${TEST_FILE}" \
|
|
127
|
+
-H "Authorization: Bearer ${api_key}" \
|
|
128
|
+
-F "file=@/tmp/private-test.txt")
|
|
129
|
+
|
|
130
|
+
body=$(echo "$response" | sed '$d')
|
|
131
|
+
status=$(echo "$response" | tail -n 1)
|
|
132
|
+
|
|
133
|
+
if [ "$status" -ge 200 ] && [ "$status" -lt 300 ]; then
|
|
134
|
+
print_success "File uploaded to private bucket ($status)"
|
|
135
|
+
if command -v jq &> /dev/null && echo "$body" | jq . >/dev/null 2>&1; then
|
|
136
|
+
echo "$body" | jq '.'
|
|
137
|
+
else
|
|
138
|
+
echo "Response: $body"
|
|
139
|
+
fi
|
|
140
|
+
else
|
|
141
|
+
print_fail "File upload to private bucket failed ($status)"
|
|
142
|
+
echo "Error: $body"
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
# Step 5: Test accessing PUBLIC file WITHOUT API key
|
|
146
|
+
print_info "5️⃣ Testing PUBLIC file access WITHOUT API key..."
|
|
147
|
+
echo " Accessing: ${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}/objects/${TEST_FILE}"
|
|
148
|
+
HTTP_CODE=$(curl -s -L -o /tmp/public-response.txt -w "%{http_code}" "${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}/objects/${TEST_FILE}")
|
|
149
|
+
if [ "$HTTP_CODE" -eq 200 ]; then
|
|
150
|
+
print_success "Public file accessible without API key! (Status: ${HTTP_CODE})"
|
|
151
|
+
echo " 📄 Content: $(cat /tmp/public-response.txt)"
|
|
152
|
+
else
|
|
153
|
+
print_fail "Public file NOT accessible without API key (Status: ${HTTP_CODE})"
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
# Step 6: Test accessing PRIVATE file WITHOUT API key
|
|
157
|
+
print_info "6️⃣ Testing PRIVATE file access WITHOUT API key..."
|
|
158
|
+
echo " Accessing: ${API_BASE_URL}/storage/buckets/${PRIVATE_BUCKET}/objects/${TEST_FILE}"
|
|
159
|
+
HTTP_CODE=$(curl -s -o /tmp/private-response.txt -w "%{http_code}" "${API_BASE_URL}/storage/buckets/${PRIVATE_BUCKET}/objects/${TEST_FILE}")
|
|
160
|
+
if [ "$HTTP_CODE" -eq 401 ]; then
|
|
161
|
+
print_success "Private file correctly blocked without API key! (Status: ${HTTP_CODE})"
|
|
162
|
+
else
|
|
163
|
+
print_fail "Private file should NOT be accessible without API key (Status: ${HTTP_CODE})"
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
# Step 7: Test accessing PRIVATE file WITH API key
|
|
167
|
+
print_info "7️⃣ Testing PRIVATE file access WITH API key..."
|
|
168
|
+
HTTP_CODE=$(curl -s -L -o /tmp/private-auth-response.txt -w "%{http_code}" \
|
|
169
|
+
-H "Authorization: Bearer ${api_key}" \
|
|
170
|
+
"${API_BASE_URL}/storage/buckets/${PRIVATE_BUCKET}/objects/${TEST_FILE}")
|
|
171
|
+
if [ "$HTTP_CODE" -eq 200 ]; then
|
|
172
|
+
print_success "Private file accessible with API key! (Status: ${HTTP_CODE})"
|
|
173
|
+
echo " 📄 Content: $(cat /tmp/private-auth-response.txt)"
|
|
174
|
+
else
|
|
175
|
+
print_fail "Private file should be accessible with API key (Status: ${HTTP_CODE})"
|
|
176
|
+
fi
|
|
177
|
+
|
|
178
|
+
# Step 8: List all buckets
|
|
179
|
+
print_info "8️⃣ Listing all buckets..."
|
|
180
|
+
response=$(curl -s -w "\n%{http_code}" -H "Authorization: Bearer ${api_key}" "${API_BASE_URL}/storage/buckets")
|
|
181
|
+
body=$(echo "$response" | sed '$d')
|
|
182
|
+
status=$(echo "$response" | tail -n 1)
|
|
183
|
+
|
|
184
|
+
if [ "$status" -eq 200 ]; then
|
|
185
|
+
print_success "Buckets listed successfully"
|
|
186
|
+
if command -v jq &> /dev/null && echo "$body" | jq . >/dev/null 2>&1; then
|
|
187
|
+
echo "$body" | jq '.[] | "\(.name) - \(if .public then "🌍 PUBLIC" else "🔒 PRIVATE" end)"' -r 2>/dev/null || echo "Could not parse bucket list"
|
|
188
|
+
else
|
|
189
|
+
echo "Response: $body"
|
|
190
|
+
fi
|
|
191
|
+
else
|
|
192
|
+
print_fail "Failed to list buckets ($status)"
|
|
193
|
+
echo "Error: $body"
|
|
194
|
+
fi
|
|
195
|
+
|
|
196
|
+
# Step 9: Test POST upload with auto-generated key
|
|
197
|
+
print_info "9️⃣ Testing POST upload with auto-generated key..."
|
|
198
|
+
echo "This is a test file for POST upload" > /tmp/post-test.txt
|
|
199
|
+
response=$(curl -s -w "\n%{http_code}" -X POST "${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}/objects" \
|
|
200
|
+
-H "Authorization: Bearer ${api_key}" \
|
|
201
|
+
-F "file=@/tmp/post-test.txt")
|
|
202
|
+
|
|
203
|
+
body=$(echo "$response" | sed '$d')
|
|
204
|
+
status=$(echo "$response" | tail -n 1)
|
|
205
|
+
|
|
206
|
+
if [ "$status" -ge 200 ] && [ "$status" -lt 300 ]; then
|
|
207
|
+
print_success "File uploaded via POST with auto-generated key ($status)"
|
|
208
|
+
if command -v jq &> /dev/null && echo "$body" | jq . >/dev/null 2>&1; then
|
|
209
|
+
echo "$body" | jq '.'
|
|
210
|
+
# Extract the generated key for verification
|
|
211
|
+
generated_key=$(echo "$body" | jq -r '.key')
|
|
212
|
+
echo " 📝 Generated key: $generated_key"
|
|
213
|
+
# Test downloading the file with generated key
|
|
214
|
+
HTTP_CODE=$(curl -s -L -o /tmp/post-download.txt -w "%{http_code}" "${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}/objects/${generated_key}")
|
|
215
|
+
if [ "$HTTP_CODE" -eq 200 ]; then
|
|
216
|
+
print_success "Downloaded file with generated key!"
|
|
217
|
+
echo " 📄 Content: $(cat /tmp/post-download.txt)"
|
|
218
|
+
else
|
|
219
|
+
print_fail "Could not download file with generated key (Status: ${HTTP_CODE})"
|
|
220
|
+
fi
|
|
221
|
+
else
|
|
222
|
+
echo "Response: $body"
|
|
223
|
+
fi
|
|
224
|
+
else
|
|
225
|
+
print_fail "POST upload failed ($status)"
|
|
226
|
+
echo "Error: $body"
|
|
227
|
+
fi
|
|
228
|
+
|
|
229
|
+
# Step 10: Update bucket visibility
|
|
230
|
+
print_info "🔟 Testing bucket visibility update (making public bucket private)..."
|
|
231
|
+
response=$(curl -s -w "\n%{http_code}" -X PATCH "${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}" \
|
|
232
|
+
-H "Authorization: Bearer ${api_key}" \
|
|
233
|
+
-H "Content-Type: application/json" \
|
|
234
|
+
-d '{"isPublic": false}')
|
|
235
|
+
|
|
236
|
+
body=$(echo "$response" | sed '$d')
|
|
237
|
+
status=$(echo "$response" | tail -n 1)
|
|
238
|
+
|
|
239
|
+
if [ "$status" -ge 200 ] && [ "$status" -lt 300 ]; then
|
|
240
|
+
print_success "Bucket visibility updated ($status)"
|
|
241
|
+
if command -v jq &> /dev/null && echo "$body" | jq . >/dev/null 2>&1; then
|
|
242
|
+
echo "$body" | jq '.'
|
|
243
|
+
else
|
|
244
|
+
echo "Response: $body"
|
|
245
|
+
fi
|
|
246
|
+
else
|
|
247
|
+
print_fail "Bucket visibility update failed ($status)"
|
|
248
|
+
echo "Error: $body"
|
|
249
|
+
fi
|
|
250
|
+
|
|
251
|
+
# Test access again
|
|
252
|
+
echo " Testing access after update..."
|
|
253
|
+
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "${API_BASE_URL}/storage/buckets/${PUBLIC_BUCKET}/objects/${TEST_FILE}")
|
|
254
|
+
if [ "$HTTP_CODE" -eq 401 ]; then
|
|
255
|
+
print_success "Previously public file now requires authentication!"
|
|
256
|
+
else
|
|
257
|
+
print_fail "File should now require authentication (Status: ${HTTP_CODE})"
|
|
258
|
+
fi
|
|
259
|
+
|
|
260
|
+
# Cleanup temp files only
|
|
261
|
+
print_info "🧹 Cleaning up temp files..."
|
|
262
|
+
rm -f /tmp/public-test.txt /tmp/private-test.txt /tmp/public-response.txt /tmp/private-response.txt /tmp/private-auth-response.txt /tmp/post-test.txt /tmp/post-download.txt
|
|
263
|
+
|
|
264
|
+
print_success "✨ Public/Private bucket test completed!"
|
|
265
265
|
# Note: Buckets will be cleaned up automatically on exit via test-config.sh
|