{"record":{"id":"827ca5e7a356d850","repo":"santifer/career-ops","slug":"jobspresso-url-must-use-https-url","errorCode":null,"errorMessage":"jobspresso: URL must use HTTPS: ${url}","messagePattern":"jobspresso: URL must use HTTPS: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"providers/jobspresso.mjs","lineNumber":23,"sourceCode":"// (https://jobspresso.co/?feed=job_feed). The feed is public, no-auth,\n// and XML, so it is parsed in-process with the same tiny tag extractor\n// approach as providers/personio.mjs rather than adding an XML dependency.\n//\n// Wire in via a `job_boards:` entry with `provider: jobspresso`.\n\nconst FEED_URL = 'https://jobspresso.co/?feed=job_feed';\nconst TRUSTED_HOST = 'jobspresso.co';\n\n/** @param {string} url */\nfunction assertJobspressoUrl(url) {\n  let parsed;\n  try {\n    parsed = new URL(url);\n  } catch {\n    throw new Error(`jobspresso: invalid URL: ${url}`);\n  }\n  if (parsed.protocol !== \"https:\")\n    throw new Error(`jobspresso: URL must use HTTPS: ${url}`);\n  if (parsed.hostname !== TRUSTED_HOST) {\n    throw new Error(\n      `jobspresso: untrusted hostname \"${parsed.hostname}\" - must be ${TRUSTED_HOST}`,\n    );\n  }\n  return url;\n}\n\n// NaN-safe Date.parse - `|| undefined` would also coerce a valid epoch 0.\nfunction toEpochMs(value) {\n  if (!value) return undefined;\n  const parsed = Date.parse(value);\n  return Number.isNaN(parsed) ? undefined : parsed;\n}\n\n/** @type {Provider} */\nexport default {\n  id: \"jobspresso\",","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/santifer/career-ops/blob/9b17a8ac97b398a496b38e423ae24e433b43254f/providers/jobspresso.mjs#L5-L41","documentation":"Thrown by assertJobspressoUrl when the URL parses but its protocol is not https:. The shipped fetch() only passes the hardcoded https FEED_URL constant, so this cannot fire from the public contract; it is an SSRF guard that activates if the constant is changed to http: or the assert is reused on http caller input.","triggerScenarios":"Editing FEED_URL to an http:// value (e.g. a dev mirror without TLS); reusing assertJobspressoUrl on entry-supplied input using http:. The unmodified provider's constant is https and never triggers this.","commonSituations":"Forgetting the https:// scheme when changing the feed host; pointing at a local dev mirror over plain http.","solutions":["Ensure FEED_URL (or any URL passed in) uses the https: scheme.","If a dev mirror is http-only, gate the assert behind a test-only override rather than weakening the constant.","Keep the scheme and host checks reviewed together when changing endpoints."],"exampleFix":"// before\nconst FEED_URL = 'http://jobspresso.co/?feed=job_feed';\n\n// after\nconst FEED_URL = 'https://jobspresso.co/?feed=job_feed';","handlingStrategy":"validation","validationCode":"function ensureHttps(url) {\n  const u = new URL(url);\n  if (u.protocol !== 'https:') throw new Error(`not https: ${url}`);\n  return u.href;\n}","typeGuard":"/** True only for an https: absolute URL. */\nfunction isHttpsUrl(value) {\n  try { return new URL(value).protocol === 'https:'; } catch { return false; }\n}","tryCatchPattern":"try {\n  return await jobspressoProvider.fetch(entry, ctx);\n} catch (err) {\n  if (/URL must use HTTPS/.test(err.message)) {\n    console.error(`jobspresso: FEED_URL must be https — ${err.message}`);\n  }\n  throw err;\n}","preventionTips":["Always include the https:// scheme in FEED_URL and any caller URL.","Use a test-only override for http dev mirrors instead of weakening the constant.","Review scheme and host together when changing endpoints."],"tags":["ssrf","url-validation","tls","jobspresso","defense-in-depth"],"backgroundTag":null,"analyzedSha":"9b17a8ac97b398a496b38e423ae24e433b43254f","analyzedAt":"2026-08-13T00:48:39.135Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}