2026-10-18 12:16:36 -05:00
|
|
|
// Mirrors clean_camera_user_pass and REGEX_MASKED_CREDENTIAL in the backend.
|
|
|
|
|
const CREDENTIAL_QUERY_KEYS =
|
|
|
|
|
"(?:user(?:name)?|usr|login|pass(?:word|wd)?|pwd|[a-z_]*token|[a-z_]*secret|[a-z_]*private|api_?key|auth)";
|
|
|
|
|
const URL_USERINFO_PATTERN = /:\/\/(?:[^\s/:]*:\S*|[^\s/]+)@/g;
|
|
|
|
|
const CREDENTIAL_QUERY_PATTERN = new RegExp(
|
|
|
|
|
`([?&]${CREDENTIAL_QUERY_KEYS}=)[^&\\s]*`,
|
|
|
|
|
"gi",
|
|
|
|
|
);
|
|
|
|
|
const MASKED_PATTERN = new RegExp(
|
|
|
|
|
`://\\*:\\*@|[?&]${CREDENTIAL_QUERY_KEYS}=\\*(?![^&\\s])`,
|
|
|
|
|
"i",
|
|
|
|
|
);
|
2026-03-19 11:33:42 -05:00
|
|
|
|
|
|
|
|
export const isMaskedPath = (value: string): boolean =>
|
2026-10-18 12:16:36 -05:00
|
|
|
MASKED_PATTERN.test(value);
|
2026-03-19 11:33:42 -05:00
|
|
|
|
|
|
|
|
export const maskCredentials = (value: string): string => {
|
|
|
|
|
if (!value) {
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-18 12:16:36 -05:00
|
|
|
return value
|
|
|
|
|
.replace(CREDENTIAL_QUERY_PATTERN, "$1*")
|
|
|
|
|
.replace(URL_USERINFO_PATTERN, "://*:*@");
|
2026-03-19 11:33:42 -05:00
|
|
|
};
|
2026-10-18 12:16:36 -05:00
|
|
|
|
|
|
|
|
export const hasCredentials = (value: string): boolean =>
|
|
|
|
|
!!value && (isMaskedPath(value) || maskCredentials(value) !== value);
|