{"record":{"id":"c491ceb41413f773","repo":"santifer/career-ops","slug":"jobbankca-url-must-use-https-url","errorCode":null,"errorMessage":"jobbankca: URL must use HTTPS: ${url}","messagePattern":"jobbankca: URL must use HTTPS: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"providers/jobbankca.mjs","lineNumber":100,"sourceCode":"    : [];\n  return { keywords };\n}\n\n/** @param {string} keyword @param {number} page */\nexport function buildFeedUrl(keyword, page) {\n  const params = new URLSearchParams({ searchstring: keyword, locationstring: '', page: String(page) });\n  return `${FEED_URL}?${params.toString()}`;\n}\n\n/** @param {string} url */\nexport function assertJobBankUrl(url) {\n  let parsed;\n  try {\n    parsed = new URL(url);\n  } catch {\n    throw new Error(`jobbankca: invalid URL: ${url}`);\n  }\n  if (parsed.protocol !== 'https:') throw new Error(`jobbankca: URL must use HTTPS: ${url}`);\n  if (parsed.hostname !== TRUSTED_HOST) {\n    throw new Error(`jobbankca: untrusted hostname \"${parsed.hostname}\" — must be ${TRUSTED_HOST}`);\n  }\n  return url;\n}\n\n// Resolve an Atom element's inner text: unwrap CDATA, else decode entities.\nfunction extractText(inner) {\n  const cdata = inner.match(/^\\s*<!\\[CDATA\\[([\\s\\S]*?)\\]\\]>\\s*$/);\n  if (cdata) return cdata[1].trim();\n  return decodeEntities(inner).trim();\n}\n\nfunction tagText(block, tag) {\n  const m = block.match(new RegExp(`<${tag}\\\\b[^>]*>([\\\\s\\\\S]*?)</${tag}>`, 'i'));\n  return m ? extractText(m[1]) : '';\n}\n","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/santifer/career-ops/blob/1696bec4d021768e7359f9aad6b329cba883da20/providers/jobbankca.mjs#L82-L118","documentation":"assertJobBankUrl enforces that all jobbankca requests use HTTPS. After the URL parses, it checks parsed.protocol !== 'https:' and throws this error for any http:// (or other scheme) URL. This protects credentials/query traffic from plaintext transport and blocks accidental non-HTTPS redirects.","triggerScenarios":"Passing a URL string starting with http:// (e.g. 'http://jobbank.canada.ca/atom.xml') or a scheme like ftp:// to assertJobBankUrl, typically copied from an old doc or hand-typed config.","commonSituations":"Portals.yml entry written with http:// by hand, a URL scraped from an old HTTP page, or a base URL constant defined without https. Also fires if someone passes a protocol-relative '//host/path' string? No — that fails parsing, but file:// or custom schemes parse and land here.","solutions":["Change the URL scheme to https:// in the provider config","Check for a hardcoded http:// constant in your integration and update it","If the source only offers http, find the official HTTPS endpoint instead of downgrading the check","Validate the scheme in your own config loader to fail earlier with your own message"],"exampleFix":"// before\nconst url = 'http://jobbank.canada.ca/atom.xml';\n// after\nconst url = 'https://jobbank.canada.ca/atom.xml';","handlingStrategy":"validation","validationCode":"function isHttps(u) { try { return new URL(u).protocol === 'https:'; } catch { return false; } }\nif (!isHttps(cfg.url)) throw new Error(`config: feed must be HTTPS: ${cfg.url}`);","typeGuard":"function isHttpsUrl(v) {\n  try { return new URL(v).protocol === 'https:'; } catch { return false; }\n}","tryCatchPattern":"try {\n  assertJobBankUrl(url);\n} catch (e) {\n  if (e.message.includes('must use HTTPS')) {\n    console.warn(`Upgrading http→https for ${url}`);\n    return assertJobBankUrl(url.replace(/^http:/, 'https:'));\n  }\n  throw e;\n}","preventionTips":["Default to https:// in all config templates and docs","Never copy URLs from http-only legacy sources","Lint config files for 'http://' occurrences in CI","Remember this also guards against credential leakage over plaintext"],"tags":["https","url-validation","security","jobbankca"],"backgroundTag":"insecure-scheme-rejected","analyzedSha":"1696bec4d021768e7359f9aad6b329cba883da20","analyzedAt":"2026-09-01T19:19:23.111Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}