{
  "name": "New account delivered \u2192 notify + reveal step (manual approval)",
  "nodes": [
    {
      "parameters": {
        "content": "## Account delivered \u2192 notify \u2192 reveal (with approval)\nWhen a manager finalizes an account (`account.finalized`), post to Slack and **wait for a human approval** before revealing credentials.\n\nRevealing is irreversible and, on new-policy accounts, ends TokPortal Coverage. The first call returns HTTP 428 with `error.details.policy_version`; the second call sends the acknowledgement with that exact version. Both are handled below.",
        "height": 280,
        "width": 680,
        "color": 4
      },
      "id": "tp-049",
      "name": "Sticky Notetp-048",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -40,
        -320
      ]
    },
    {
      "parameters": {
        "events": [
          "account.finalized",
          "account.published"
        ],
        "options": {}
      },
      "id": "tp-050",
      "name": "Account Finalized",
      "type": "n8n-nodes-tokportal.tokPortalTrigger",
      "typeVersion": 1,
      "position": [
        0,
        60
      ],
      "credentials": {
        "tokPortalApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "message",
        "operation": "post",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "name",
          "value": "#social-ops"
        },
        "text": "=:tada: *TokPortal account delivered* \u2014 `@{{ $json.data.username }}` on {{ $json.data.platform }}\nBundle `{{ $json.data.bundle_id }}` \u00b7 Account `{{ $json.data.saved_account_id }}`\nApprove the credential reveal in n8n if you need the login (this ends managed Coverage on new-policy accounts).",
        "otherOptions": {}
      },
      "id": "tp-051",
      "name": "Slack: Account Delivered",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.2,
      "position": [
        260,
        60
      ],
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resume": "webhook",
        "httpMethod": "POST",
        "options": {}
      },
      "id": "tp-052",
      "name": "Wait for Approval",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        520,
        60
      ]
    },
    {
      "parameters": {
        "resource": "account",
        "operation": "revealCredentials",
        "accountId": "={{ $(\"Account Finalized\").item.json.data.saved_account_id }}",
        "acknowledgeSupportForfeit": false
      },
      "id": "tp-053",
      "name": "Reveal (First Call \u2192 428)",
      "type": "n8n-nodes-tokportal.tokPortal",
      "typeVersion": 1,
      "position": [
        780,
        60
      ],
      "credentials": {
        "tokPortalApi": {
          "name": "<your credential>"
        }
      },
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "// If the first call already returned credentials (prior-policy account), pass them through.\n// Otherwise read policy_version from the 428 error details.\nconst j = $input.first().json;\nif (j.username || j.password || j.credentials) {\n  return [{ json: { revealed: true, ...j } }];\n}\nconst err = j.error || {};\nconst details = err.details || (err.description && typeof err.description === 'object' ? err.description : {}) || {};\nlet policyVersion = details.policy_version;\nif (!policyVersion && typeof err.message === 'string') {\n  const m = err.message.match(/policy_version[^a-zA-Z0-9_.-]*([a-zA-Z0-9_.-]+)/);\n  if (m) policyVersion = m[1];\n}\nif (!policyVersion && typeof j.message === 'string') {\n  const m = j.message.match(/policy_version[^a-zA-Z0-9_.-]*([a-zA-Z0-9_.-]+)/);\n  if (m) policyVersion = m[1];\n}\nif (!policyVersion) {\n  throw new Error('Could not find policy_version in the 428 response: ' + JSON.stringify(j).slice(0, 500));\n}\nreturn [{ json: { revealed: false, policy_version: policyVersion } }];"
      },
      "id": "tp-054",
      "name": "Extract Policy Version",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1040,
        60
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "id": "r1",
              "leftValue": "={{ $json.revealed }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "tp-055",
      "name": "Already Revealed?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        1300,
        60
      ]
    },
    {
      "parameters": {
        "resource": "account",
        "operation": "revealCredentials",
        "accountId": "={{ $(\"Account Finalized\").item.json.data.saved_account_id }}",
        "acknowledgeSupportForfeit": true,
        "policyVersion": "={{ $json.policy_version }}"
      },
      "id": "tp-056",
      "name": "Reveal (Acknowledged)",
      "type": "n8n-nodes-tokportal.tokPortal",
      "typeVersion": 1,
      "position": [
        1560,
        180
      ],
      "credentials": {
        "tokPortalApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "message",
        "operation": "post",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "name",
          "value": "#social-ops"
        },
        "text": "=:key: Credentials for `@{{ $(\"Account Finalized\").item.json.data.username }}` were revealed by n8n. Retrieve them from the execution log (never post secrets in Slack).",
        "otherOptions": {}
      },
      "id": "tp-057",
      "name": "Slack: Credentials Ready",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.2,
      "position": [
        1820,
        60
      ],
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Account Finalized": {
      "main": [
        [
          {
            "node": "Slack: Account Delivered",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack: Account Delivered": {
      "main": [
        [
          {
            "node": "Wait for Approval",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait for Approval": {
      "main": [
        [
          {
            "node": "Reveal (First Call \u2192 428)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Reveal (First Call \u2192 428)": {
      "main": [
        [
          {
            "node": "Extract Policy Version",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Policy Version": {
      "main": [
        [
          {
            "node": "Already Revealed?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Already Revealed?": {
      "main": [
        [
          {
            "node": "Slack: Credentials Ready",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Reveal (Acknowledged)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Reveal (Acknowledged)": {
      "main": [
        [
          {
            "node": "Slack: Credentials Ready",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": [
    {
      "name": "TokPortal"
    }
  ]
}