/*
 * Copyright 2026, Jaime Terrats.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { existsSync } from 'node:fs';
import { join } from 'node:path';
import { generateSecurityWorkflows } from '../generators/workflows/security.js';
import { consultativeDesign, deployment, documentationStandards, flsAndCrudEnforcement, generatedPromptsProtocol, getSharedSectionLines, interactionPreferences, salesforceReferences, semanticCommits, } from './shared-sections.js';
export const securityProfile = {
    id: 'security',
    label: 'Security / Compliance',
    ruleFile: 'security-standards.mdc',
    extensions: ['salesforce.salesforcedx-vscode', 'salesforce.sfdx-code-analyzer-vscode', 'financialforce.lana'],
    capabilities: ['deploy', 'code-analysis', 'prompt-registry', 'declare-points'],
    cursorScope: 'description',
    detect(cwd) {
        return existsSync(join(cwd, 'force-app'));
    },
    workflows: generateSecurityWorkflows,
    ruleContent() {
        return [
            '---',
            'description: Salesforce Security / Compliance Standards',
            'globs:',
            'alwaysApply: true',
            '---',
            '',
            '# Salesforce Security / Compliance Standards',
            '',
            '> Role: Security / Compliance Specialist — Salesforce Professional Services.',
            '',
            ...consultativeDesign('security architecture and access-control decisions'),
            '',
            '## Organization-Wide Defaults (OWD) & Sharing Model',
            '- Start with the **most restrictive OWD** (Private) and open access via sharing rules.',
            '- Use **Criteria-Based Sharing Rules** when access depends on field values (e.g., region, status).',
            '- Use **Owner-Based Sharing Rules** when access depends on record ownership (e.g., role hierarchy).',
            '- Review OWD quarterly: run Sharing Model reports to detect over-permissioned objects.',
            '- For objects containing PII or financial data, OWD must be **Private** — no exceptions without documented approval.',
            '- Use **Apex Managed Sharing** only when declarative sharing rules cannot meet the requirement. Document the reason.',
            '',
            '## Field-Level Security (FLS) Enforcement',
            '- **Always enforce FLS in Apex.** Never assume the running user has access to a field.',
            '- Use `Schema.SObjectType.<Object>.fields.<Field>.getDescribe().isAccessible()` before reads.',
            '- Use `Schema.SObjectType.<Object>.fields.<Field>.getDescribe().isCreateable()` / `.isUpdateable()` before writes.',
            '- Prefer `Security.stripInaccessible()` to automatically remove inaccessible fields from DML operations.',
            '- `stripInaccessible(AccessType.READABLE, records)` before returning data to the UI.',
            '- `stripInaccessible(AccessType.CREATABLE, records)` before insert.',
            '- `stripInaccessible(AccessType.UPDATABLE, records)` before update.',
            '',
            '## SOQL Security',
            '- **Always use `WITH SECURITY_ENFORCED`** in SOQL queries to enforce FLS and object-level security.',
            "- Alternative: `WITH USER_MODE` for queries that should respect the running user's full permission set.",
            '- **Never use `WITHOUT SECURITY_ENFORCED`** unless in a clearly documented system-context operation.',
            '- Guard against **SOQL injection**: use bind variables (`:variable`) instead of string concatenation in dynamic SOQL.',
            '- When dynamic SOQL is unavoidable, use `String.escapeSingleQuotes()` on all user-supplied values.',
            '',
            '## CRUD Checks Before DML',
            '- Before **insert**: verify `Schema.SObjectType.<Object>.isCreateable()`.',
            '- Before **update**: verify `Schema.SObjectType.<Object>.isUpdateable()`.',
            '- Before **delete**: verify `Schema.SObjectType.<Object>.isDeletable()`.',
            '- Before **read**: verify `Schema.SObjectType.<Object>.isAccessible()`.',
            '- Throw a descriptive exception (using Custom Labels) when CRUD checks fail — never silently skip the operation.',
            '',
            '## Platform Encryption (Shield)',
            '- **Deterministic encryption**: use for fields that need equality-based filtering, grouping, or unique constraints.',
            '- **Probabilistic encryption**: use for fields that only need display/export (stronger security, no filter support).',
            '- Field selection criteria: encrypt fields containing PII, PHI, financial data, or government IDs.',
            '- Never encrypt fields used in ORDER BY, LIKE, or formula calculations — they are incompatible.',
            '- Document encryption decisions in an **Encryption Impact Assessment** before enabling.',
            '- Rotate tenant secrets on the schedule defined by your compliance framework (SOC 2, HIPAA, etc.).',
            '',
            '## Event Monitoring & Transaction Security',
            '- Enable **Real-Time Event Monitoring** for Login, API, Report Export, and Data Export events.',
            '- Create **Transaction Security Policies** for high-risk operations: bulk data exports, login from unknown IPs, excessive API calls.',
            '- Use **Condition Builder** for policy conditions (no Apex) unless complex logic is required.',
            '- Route policy notifications to a dedicated security Chatter group or external SIEM.',
            '- Review Event Monitoring logs monthly for anomalies: unusual login patterns, bulk exports, permission escalations.',
            '',
            '## Login Flows & Session Settings',
            '- Enforce **MFA** for all user profiles — no exceptions for internal users.',
            '- Set session timeout to ≤ 2 hours for standard users, ≤ 30 minutes for admin profiles.',
            '- Enable **Login IP Ranges** on profiles to restrict access to corporate networks / VPN.',
            '- Use **Login Flows** to inject custom verification steps (e.g., terms acceptance, device registration).',
            '- Disable concurrent sessions unless there is a documented business justification.',
            '- Lock sessions to the IP address that created them (`Session Settings > Lock sessions to the IP address from which they originated`).',
            '',
            '## Health Check Score Optimization',
            '- Target a **Health Check score of 90+** at all times.',
            '- Address all **HIGH-risk** settings first: password policies, session settings, login restrictions.',
            '- Review Health Check quarterly. Document deviations with a risk-acceptance form signed by the Security Lead.',
            "- Customize the **Health Check baseline** to match your org's compliance framework.",
            '',
            '## Named Credentials & External Callouts',
            '- **ALWAYS use Named Credentials** for external integrations — never hardcode endpoints, tokens, or credentials.',
            '- Prefer **certificate-based authentication** (mutual TLS) over username/password where the external system supports it.',
            '- Store API keys in **Named Credentials** or **Custom Metadata Types** with field-level encryption — never in code.',
            '- Validate that callout endpoints use HTTPS. Block HTTP endpoints via **CSP Trusted Sites**.',
            '',
            '## Custom Permissions for Feature Gates',
            "- **Never hardcode Profile names** in Apex or validation rules. Use `FeatureManagement.checkPermission('Custom_Permission_Name')`.",
            '- Create granular Custom Permissions: `BypassValidation`, `ExportSensitiveData`, `AdminOverride`, etc.',
            '- Assign Custom Permissions via **Permission Sets** — never directly on Profiles.',
            '',
            '## Content Security Policy (CSP)',
            '- In LWC: avoid `lwc:dom="manual"` and `innerHTML` — they bypass CSP protections.',
            '- Use the **Lightning Locker Service / Lightning Web Security** model for component isolation.',
            '- In Visualforce: set `<apex:page>` attribute `showHeader="true"` to inherit platform CSP headers.',
            '- Register all third-party script origins in **CSP Trusted Sites** — never use wildcard origins.',
            '- Avoid inline `<script>` blocks in Visualforce; move JavaScript to static resources.',
            '',
            '## OWASP Top 10 — Salesforce Mapping',
            '- **Injection (A03):** Prevent SOQL injection via bind variables. Prevent XSS in Visualforce via `HTMLENCODE()`, `JSENCODE()`, `URLENCODE()`.',
            '- **Broken Access Control (A01):** Enforce CRUD/FLS in every Apex entry point. Use `with sharing` by default.',
            '- **Cryptographic Failures (A02):** Use Shield Platform Encryption for sensitive data at rest. Use HTTPS for data in transit.',
            '- **Security Misconfiguration (A05):** Run Health Check regularly. Remove unused Connected Apps, remote sites, and named credentials.',
            '- **Vulnerable Components (A06):** Audit managed packages quarterly. Remove unused packages.',
            '- **SSRF (A10):** Validate callout URLs against an allowlist before making HTTP requests from Apex.',
            '- **CSRF:** Salesforce platform handles CSRF tokens automatically for standard pages. For custom Visualforce, never disable `@RemoteAction` CSRF protection.',
            '',
            '## Connected App Security',
            '- Define **minimal OAuth scopes** — never grant `full` unless absolutely required.',
            '- Apply **IP restrictions** on Connected Apps to limit access to known CIDR ranges.',
            '- Use **certificate-based authentication** (JWT Bearer flow) for server-to-server integrations.',
            '- Set token expiration policies: access tokens ≤ 2 hours, refresh tokens ≤ 24 hours for non-service accounts.',
            '- Review Connected App usage quarterly. Revoke apps that are no longer in use.',
            '',
            '## Permission Set Groups Strategy',
            '- Model access around **job functions**, not technical roles. Example: `CaseManager_PSG`, `FieldTech_PSG`.',
            '- Include a **muting Permission Set** in each group to subtract specific permissions when needed.',
            '- Audit Permission Set Group membership quarterly: remove users who changed roles.',
            '- Never assign Permission Sets directly to users when a PSG covers the use case.',
            '',
            '## Sensitive Data Classification & Handling',
            '- Classify all custom fields: **Public**, **Internal**, **Confidential**, **Restricted**.',
            '- **Restricted** fields (PII, PHI, financial): encrypt via Shield, enforce FLS, log access via Event Monitoring.',
            '- **Confidential** fields: enforce FLS, include in reports only when user profile allows.',
            '- Mask sensitive data in **sandbox seeding** — use `SandboxPostCopy` interface to anonymize.',
            '- Implement data retention policies via archival batch jobs. Never keep sensitive data beyond the retention window.',
            '',
            ...flsAndCrudEnforcement(),
            '- **`Security.stripInaccessible()` is the preferred pattern** over manual `isAccessible()`/`isCreateable()` field-by-field checks.',
            '- Apply before every DML entry point, not just in service classes — enforce at the boundary closest to user input.',
            '- Pattern reference:',
            '  ```apex',
            '  SObjectAccessDecision result = Security.stripInaccessible(AccessType.CREATABLE, records);',
            '  insert result.getRecords();',
            '  ```',
            '- AccessType enum: `READABLE` (before returning data), `CREATABLE` (before insert), `UPDATABLE` (before update).',
            '- READABLE stripping also removes fields the user cannot see — always apply before serializing records to LWC or REST.',
            '- Combine with `WITH USER_MODE` in SOQL for defense-in-depth: SOQL enforces object/field access, `stripInaccessible` catches DML.',
            '',
            '## SAST Gate (Code Analyzer)',
            '- **Run `sf code-analyzer run` before every pull request.** No PR merges if Code Analyzer reports security violations.',
            '- Command: `sf code-analyzer run --target force-app/ --rule-thread-timeout 60000 --severity-threshold 3`',
            '- Severity 1-2 (critical): block merge immediately. Severity 3 (high): block merge, require documented exception.',
            '- Include in CI pipeline as a required check — not optional.',
            '- Key PMD rules to enforce: `ApexCRUDViolation`, `ApexSharingViolations`, `ApexSOQLInjection`, `ApexInsecureEndpoint`, `ApexOpenRedirect`.',
            '- Enable **Retire.js** ruleset in Code Analyzer for LWC to flag vulnerable static resource libraries.',
            '- Document any accepted rule suppressions with business justification in a `suppressions.json` and get Security Lead sign-off.',
            '',
            ...generatedPromptsProtocol(),
            '',
            ...documentationStandards(),
            '',
            ...deployment(),
            '',
            ...semanticCommits(),
            '',
            '## Sub-agent Handover',
            '- Pass to sub-agents: OWD baseline, encryption status, Permission Set Group naming convention, and compliance framework (SOC 2 / HIPAA / GDPR).',
            '- Sub-agents must follow: `WITH SECURITY_ENFORCED` in all SOQL, `stripInaccessible()` on all DML, Named Credentials for callouts.',
            '',
            ...salesforceReferences(),
            ...getSharedSectionLines('security'),
            '',
            ...interactionPreferences('security'),
        ].join('\n');
    },
};
//# sourceMappingURL=security.js.map