diff --git a/bun.lock b/bun.lock index ff3f6e1..7b003ec 100644 --- a/bun.lock +++ b/bun.lock @@ -1,5 +1,6 @@ { "lockfileVersion": 1, + "configVersion": 0, "workspaces": { "": { "name": "dsas-cca-backend-bun", @@ -16,9 +17,10 @@ }, "devDependencies": { "@types/bun": "latest", + "typescript-language-server": "^5.1.3", }, "peerDependencies": { - "typescript": "^5", + "typescript": "^5.9.3", }, }, }, @@ -247,7 +249,9 @@ "type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="], - "typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="], + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + + "typescript-language-server": ["typescript-language-server@5.1.3", "", { "bin": { "typescript-language-server": "lib/cli.mjs" } }, "sha512-r+pAcYtWdN8tKlYZPwiiHNA2QPjXnI02NrW5Sf2cVM3TRtuQ3V9EKKwOxqwaQ0krsaEXk/CbN90I5erBuf84Vg=="], "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], diff --git a/example.env b/example.env index 45498ac..7641cc0 100644 --- a/example.env +++ b/example.env @@ -3,7 +3,8 @@ API_PASSWORD= PORT=3000 FIXED_STAFF_ACTIVITY_ID=7095 ALLOWED_ORIGINS=* -S3_ENDPOINT= +S3_ENDPOINT= +S3_PUBLIC_URL= S3_BUCKET_NAME= S3_ACCESS_KEY_ID= S3_SECRET_ACCESS_KEY= diff --git a/extract-login-form.js b/extract-login-form.js new file mode 100644 index 0000000..79715d4 --- /dev/null +++ b/extract-login-form.js @@ -0,0 +1,112 @@ +import { chromium } from 'playwright'; + +async function extractLoginForm() { + const browser = await chromium.launch({ headless: true }); + const page = await browser.newPage(); + + console.log('Navigating to login page...\n'); + await page.goto('https://engage.nkcswx.cn/Login.aspx'); + await page.waitForLoadState('networkidle'); + + // Extract all form fields + const formFields = await page.evaluate(() => { + const form = document.querySelector('form'); + if (!form) return { error: 'No form found' }; + + const fields = []; + + // Get all inputs from the form + const inputs = form.querySelectorAll('input, select, textarea'); + inputs.forEach((input, index) => { + fields.push({ + index, + type: input.tagName, + name: input.name || '(no name)', + id: input.id || '(no id)', + inputType: input.type || 'N/A', + value: input.type === 'password' ? '[HIDDEN]' : (input.value || '(empty)'), + placeholder: input.placeholder || '(none)', + required: input.required ? 'yes' : 'no', + autocomplete: input.autocomplete || '(none)' + }); + }); + + // Get form attributes + const formAttrs = { + action: form.action, + method: form.method, + enctype: form.enctype, + target: form.target + }; + + return { formAttrs, fields }; + }); + + if (formFields.error) { + console.error(formFields.error); + await browser.close(); + return; + } + + console.log('='.repeat(70)); + console.log('FORM ATTRIBUTES'); + console.log('='.repeat(70)); + console.log(`Action: ${formFields.formAttrs.action}`); + console.log(`Method: ${formFields.formAttrs.method}`); + console.log(`Enctype: ${formFields.formAttrs.enctype}`); + console.log(`Target: ${formFields.formAttrs.target || '(default)'}`); + console.log(''); + + console.log('='.repeat(70)); + console.log('ALL FORM FIELDS'); + console.log('='.repeat(70)); + console.log(''); + + // Group fields by type + const hiddenFields = formFields.fields.filter(f => f.inputType === 'hidden'); + const visibleFields = formFields.fields.filter(f => f.inputType !== 'hidden'); + + // Show hidden fields first (critical for ASP.NET) + if (hiddenFields.length > 0) { + console.log('šŸ“¦ HIDDEN FIELDS (critical for form submission):'); + console.log('-'.repeat(70)); + hiddenFields.forEach(field => { + console.log(` Name: ${field.name}`); + console.log(` Value: ${field.value.substring(0, 80)}${field.value.length > 80 ? '...' : ''}`); + console.log(` Length: ${field.value.length} chars`); + console.log(''); + }); + } + + // Show visible fields + if (visibleFields.length > 0) { + console.log('\nšŸ“ VISIBLE FIELDS:'); + console.log('-'.repeat(70)); + visibleFields.forEach(field => { + console.log(` Name: ${field.name}`); + console.log(` Type: ${field.inputType}`); + console.log(` ID: ${field.id}`); + console.log(` Placeholder: ${field.placeholder}`); + console.log(` Required: ${field.required}`); + console.log(` Autocomplete: ${field.autocomplete}`); + console.log(''); + }); + } + + // Summary of field names + console.log('='.repeat(70)); + console.log('FIELD NAME SUMMARY (for authentication payload):'); + console.log('='.repeat(70)); + formFields.fields.forEach(field => { + const marker = field.inputType === 'hidden' ? '[HIDDEN]' : '[VISIBLE]'; + console.log(` ${marker} ${field.name}`); + }); + + // Take a screenshot for visual reference + await page.screenshot({ path: 'login-page-screenshot.png', fullPage: true }); + console.log('\nšŸ“ø Screenshot saved to: login-page-screenshot.png'); + + await browser.close(); +} + +extractLoginForm().catch(console.error); diff --git a/package.json b/package.json index 80197f0..cc50cf4 100644 --- a/package.json +++ b/package.json @@ -6,10 +6,11 @@ "dev": "bun run --watch index.ts" }, "devDependencies": { - "@types/bun": "latest" + "@types/bun": "latest", + "typescript-language-server": "^5.1.3" }, "peerDependencies": { - "typescript": "^5" + "typescript": "^5.9.3" }, "dependencies": { "axios": "^1.9.0", diff --git a/services/s3-service.ts b/services/s3-service.ts index c620d75..aeb573a 100644 --- a/services/s3-service.ts +++ b/services/s3-service.ts @@ -15,6 +15,7 @@ const S3_REGION = process.env.S3_REGION; const S3_ACCESS_KEY_ID = process.env.S3_ACCESS_KEY_ID; const S3_SECRET_ACCESS_KEY = process.env.S3_SECRET_ACCESS_KEY; const BUCKET_NAME = process.env.S3_BUCKET_NAME; +const S3_PUBLIC_URL = process.env.S3_PUBLIC_URL; const PUBLIC_URL_FILE_PREFIX = (process.env.S3_PUBLIC_URL_PREFIX || 'files').replace(/\/$/, ''); // Initialize S3 client @@ -195,6 +196,7 @@ export async function deleteS3Objects(objectKeysArray: string[]): Promise