@hasna/logs 0.3.30 → 0.3.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
runJob,
|
|
9
9
|
structuredLogToEntry,
|
|
10
10
|
validateStructuredLogReferences
|
|
11
|
-
} from "../index-
|
|
11
|
+
} from "../index-a0gz0zzc.js";
|
|
12
12
|
import {
|
|
13
13
|
PACKAGE_VERSION,
|
|
14
14
|
createPage,
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
searchTestReports,
|
|
31
31
|
summarizeLogs,
|
|
32
32
|
validateUniversalEventInput
|
|
33
|
-
} from "../index-
|
|
33
|
+
} from "../index-he072p17.js";
|
|
34
34
|
import {
|
|
35
35
|
getStorageStatus,
|
|
36
36
|
storagePull,
|
|
@@ -658,6 +658,12 @@ function redactString(input, path = "$") {
|
|
|
658
658
|
if (matched)
|
|
659
659
|
fields.push(`${path}:${label}`);
|
|
660
660
|
}
|
|
661
|
+
const cookieResult = redactCookieHeaderText(output);
|
|
662
|
+
if (cookieResult.replacements > 0) {
|
|
663
|
+
output = cookieResult.value;
|
|
664
|
+
fields.push(`${path}:cookie_header`);
|
|
665
|
+
replacements += cookieResult.replacements;
|
|
666
|
+
}
|
|
661
667
|
return {
|
|
662
668
|
value: output,
|
|
663
669
|
report: { applied: replacements > 0, fields, replacements }
|
|
@@ -726,6 +732,191 @@ function redactionMetadata(report) {
|
|
|
726
732
|
function emptyReport() {
|
|
727
733
|
return { applied: false, fields: [], replacements: 0 };
|
|
728
734
|
}
|
|
735
|
+
function redactCookieHeaderText(input) {
|
|
736
|
+
const ranges = [];
|
|
737
|
+
const keyPattern = /set-cookie|cookie/gi;
|
|
738
|
+
let match = keyPattern.exec(input);
|
|
739
|
+
while (match) {
|
|
740
|
+
const keyStart = match.index;
|
|
741
|
+
const keyEnd = keyStart + match[0].length;
|
|
742
|
+
if (hasCookieKeyBoundary(input, keyStart, keyEnd)) {
|
|
743
|
+
const quotedKey = parseQuotedKeyContext(input, keyStart, keyEnd);
|
|
744
|
+
if (quotedKey) {
|
|
745
|
+
const afterKey = skipHorizontalWhitespace(input, quotedKey.afterKey);
|
|
746
|
+
if (input[afterKey] === ":") {
|
|
747
|
+
collectCookieMapValueRanges(input, afterKey + 1, ranges);
|
|
748
|
+
match = keyPattern.exec(input);
|
|
749
|
+
continue;
|
|
750
|
+
}
|
|
751
|
+
if (input[afterKey] === ",") {
|
|
752
|
+
const value = parseQuotedString(input, skipHorizontalWhitespace(input, afterKey + 1));
|
|
753
|
+
if (value)
|
|
754
|
+
ranges.push(quotedStringRange(value));
|
|
755
|
+
match = keyPattern.exec(input);
|
|
756
|
+
continue;
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
collectPlainCookieHeaderRange(input, keyEnd, ranges);
|
|
760
|
+
}
|
|
761
|
+
match = keyPattern.exec(input);
|
|
762
|
+
}
|
|
763
|
+
return applyReplacementRanges(input, ranges);
|
|
764
|
+
}
|
|
765
|
+
function hasCookieKeyBoundary(input, start, end) {
|
|
766
|
+
return !isCookieKeyCharacter(input[start - 1]) && !isCookieKeyCharacter(input[end]);
|
|
767
|
+
}
|
|
768
|
+
function isCookieKeyCharacter(value) {
|
|
769
|
+
return value !== undefined && /[A-Za-z0-9_-]/.test(value);
|
|
770
|
+
}
|
|
771
|
+
function parseQuotedKeyContext(input, start, end) {
|
|
772
|
+
const before = readQuoteBefore(input, start);
|
|
773
|
+
const after = readQuoteAt(input, end);
|
|
774
|
+
if (!before || !after)
|
|
775
|
+
return null;
|
|
776
|
+
if (before.quote !== after.quote || before.escaped !== after.escaped) {
|
|
777
|
+
return null;
|
|
778
|
+
}
|
|
779
|
+
return { afterKey: end + after.length };
|
|
780
|
+
}
|
|
781
|
+
function collectCookieMapValueRanges(input, start, ranges) {
|
|
782
|
+
const valueStart = skipHorizontalWhitespace(input, start);
|
|
783
|
+
if (input[valueStart] === "[") {
|
|
784
|
+
collectQuotedArrayValueRanges(input, valueStart, ranges);
|
|
785
|
+
return;
|
|
786
|
+
}
|
|
787
|
+
const value = parseQuotedString(input, valueStart);
|
|
788
|
+
if (value)
|
|
789
|
+
ranges.push(quotedStringRange(value));
|
|
790
|
+
}
|
|
791
|
+
function collectQuotedArrayValueRanges(input, start, ranges) {
|
|
792
|
+
let index = start + 1;
|
|
793
|
+
while (index < input.length) {
|
|
794
|
+
index = skipHorizontalWhitespace(input, index);
|
|
795
|
+
if (input[index] === "]" || isLineBreak(input[index]))
|
|
796
|
+
return;
|
|
797
|
+
const value = parseQuotedString(input, index);
|
|
798
|
+
if (value) {
|
|
799
|
+
ranges.push(quotedStringRange(value));
|
|
800
|
+
index = value.end;
|
|
801
|
+
continue;
|
|
802
|
+
}
|
|
803
|
+
index += 1;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
function collectPlainCookieHeaderRange(input, start, ranges) {
|
|
807
|
+
let index = skipHorizontalWhitespace(input, start);
|
|
808
|
+
if (input[index] !== ":" && input[index] !== "=")
|
|
809
|
+
return;
|
|
810
|
+
index = skipHorizontalWhitespace(input, index + 1);
|
|
811
|
+
const end = findLineEnd(input, index);
|
|
812
|
+
if (end > index)
|
|
813
|
+
ranges.push({ start: index, end });
|
|
814
|
+
}
|
|
815
|
+
function parseQuotedString(input, start) {
|
|
816
|
+
const open = readQuoteAt(input, start);
|
|
817
|
+
if (!open)
|
|
818
|
+
return null;
|
|
819
|
+
const contentStart = start + open.length;
|
|
820
|
+
const closeStart = findClosingQuote(input, contentStart, open);
|
|
821
|
+
if (closeStart === null)
|
|
822
|
+
return null;
|
|
823
|
+
return {
|
|
824
|
+
contentStart,
|
|
825
|
+
contentEnd: closeStart,
|
|
826
|
+
end: closeStart + open.length
|
|
827
|
+
};
|
|
828
|
+
}
|
|
829
|
+
function quotedStringRange(value) {
|
|
830
|
+
return { start: value.contentStart, end: value.contentEnd };
|
|
831
|
+
}
|
|
832
|
+
function findClosingQuote(input, start, token) {
|
|
833
|
+
let index = start;
|
|
834
|
+
while (index < input.length) {
|
|
835
|
+
if (isLineBreak(input[index]))
|
|
836
|
+
return null;
|
|
837
|
+
if (token.escaped) {
|
|
838
|
+
if (input[index] === "\\" && input[index + 1] === token.quote) {
|
|
839
|
+
const slashCount = countContiguousBackslashesEndingAt(input, index);
|
|
840
|
+
if (slashCount === 1)
|
|
841
|
+
return index;
|
|
842
|
+
index += 2;
|
|
843
|
+
continue;
|
|
844
|
+
}
|
|
845
|
+
index += 1;
|
|
846
|
+
continue;
|
|
847
|
+
}
|
|
848
|
+
if (input[index] === "\\") {
|
|
849
|
+
index += 2;
|
|
850
|
+
continue;
|
|
851
|
+
}
|
|
852
|
+
if (input[index] === token.quote)
|
|
853
|
+
return index;
|
|
854
|
+
index += 1;
|
|
855
|
+
}
|
|
856
|
+
return null;
|
|
857
|
+
}
|
|
858
|
+
function readQuoteBefore(input, index) {
|
|
859
|
+
const escapedQuote = input.slice(index - 2, index);
|
|
860
|
+
if (escapedQuote === "\\\"" || escapedQuote === "\\'") {
|
|
861
|
+
return { quote: escapedQuote[1], escaped: true, length: 2 };
|
|
862
|
+
}
|
|
863
|
+
const quote = input[index - 1];
|
|
864
|
+
return quote === '"' || quote === "'" ? { quote, escaped: false, length: 1 } : null;
|
|
865
|
+
}
|
|
866
|
+
function readQuoteAt(input, index) {
|
|
867
|
+
const escapedQuote = input.slice(index, index + 2);
|
|
868
|
+
if (escapedQuote === "\\\"" || escapedQuote === "\\'") {
|
|
869
|
+
return { quote: escapedQuote[1], escaped: true, length: 2 };
|
|
870
|
+
}
|
|
871
|
+
const quote = input[index];
|
|
872
|
+
return quote === '"' || quote === "'" ? { quote, escaped: false, length: 1 } : null;
|
|
873
|
+
}
|
|
874
|
+
function skipHorizontalWhitespace(input, start) {
|
|
875
|
+
let index = start;
|
|
876
|
+
while (input[index] === " " || input[index] === "\t")
|
|
877
|
+
index += 1;
|
|
878
|
+
return index;
|
|
879
|
+
}
|
|
880
|
+
function findLineEnd(input, start) {
|
|
881
|
+
let index = start;
|
|
882
|
+
while (index < input.length && !isLineBreak(input[index]))
|
|
883
|
+
index += 1;
|
|
884
|
+
return index;
|
|
885
|
+
}
|
|
886
|
+
function isLineBreak(value) {
|
|
887
|
+
return value === `
|
|
888
|
+
` || value === "\r";
|
|
889
|
+
}
|
|
890
|
+
function countContiguousBackslashesEndingAt(input, index) {
|
|
891
|
+
let count = 0;
|
|
892
|
+
let cursor = index;
|
|
893
|
+
while (cursor >= 0 && input[cursor] === "\\") {
|
|
894
|
+
count += 1;
|
|
895
|
+
cursor -= 1;
|
|
896
|
+
}
|
|
897
|
+
return count;
|
|
898
|
+
}
|
|
899
|
+
function applyReplacementRanges(input, ranges) {
|
|
900
|
+
const sorted = ranges.filter((range) => range.end > range.start).sort((a, b) => a.start - b.start);
|
|
901
|
+
const deduped = [];
|
|
902
|
+
let lastEnd = -1;
|
|
903
|
+
for (const range of sorted) {
|
|
904
|
+
if (range.start < lastEnd)
|
|
905
|
+
continue;
|
|
906
|
+
deduped.push(range);
|
|
907
|
+
lastEnd = range.end;
|
|
908
|
+
}
|
|
909
|
+
let value = input;
|
|
910
|
+
let replacements = 0;
|
|
911
|
+
for (let index = deduped.length - 1;index >= 0; index -= 1) {
|
|
912
|
+
const range = deduped[index];
|
|
913
|
+
if (value.slice(range.start, range.end) === REDACTED)
|
|
914
|
+
continue;
|
|
915
|
+
value = `${value.slice(0, range.start)}${REDACTED}${value.slice(range.end)}`;
|
|
916
|
+
replacements += 1;
|
|
917
|
+
}
|
|
918
|
+
return { value, replacements };
|
|
919
|
+
}
|
|
729
920
|
function isSensitiveFlag(value) {
|
|
730
921
|
const normalized = value.trim().replace(/^-+/, "");
|
|
731
922
|
if (!normalized || normalized.includes("="))
|
package/dist/mcp/index.js
CHANGED
package/dist/server/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
startScheduler,
|
|
9
9
|
structuredLogPayloadToEntries,
|
|
10
10
|
validateStructuredLogReferences
|
|
11
|
-
} from "../index-
|
|
11
|
+
} from "../index-a0gz0zzc.js";
|
|
12
12
|
import {
|
|
13
13
|
countLogs
|
|
14
14
|
} from "../index-gcd14q2f.js";
|
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
updateAlertRule,
|
|
51
51
|
updateProject,
|
|
52
52
|
validateUniversalEventInput
|
|
53
|
-
} from "../index-
|
|
53
|
+
} from "../index-he072p17.js";
|
|
54
54
|
import {
|
|
55
55
|
getDb,
|
|
56
56
|
getIssue,
|
|
@@ -2148,12 +2148,12 @@ function isLocalOpenModeEnabled() {
|
|
|
2148
2148
|
}
|
|
2149
2149
|
function isTrustedLocalRequest(c) {
|
|
2150
2150
|
const url = new URL(c.req.url);
|
|
2151
|
-
const
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
return
|
|
2151
|
+
const hosts = [
|
|
2152
|
+
hostWithoutPort(c.req.header("host")),
|
|
2153
|
+
url.hostname,
|
|
2154
|
+
...forwardedHosts(c.req.header("x-forwarded-host"))
|
|
2155
|
+
].filter((host) => Boolean(host));
|
|
2156
|
+
return hosts.length > 0 && hosts.every((host) => isLocalHost(host)) && isLocalOrigin(c.req.header("origin"));
|
|
2157
2157
|
}
|
|
2158
2158
|
function hostWithoutPort(value) {
|
|
2159
2159
|
if (!value)
|
|
@@ -2162,6 +2162,9 @@ function hostWithoutPort(value) {
|
|
|
2162
2162
|
return value.slice(1, value.indexOf("]"));
|
|
2163
2163
|
return value.split(":")[0] || null;
|
|
2164
2164
|
}
|
|
2165
|
+
function forwardedHosts(value) {
|
|
2166
|
+
return value?.split(",").map((host) => hostWithoutPort(host.trim())).filter((host) => Boolean(host)) ?? [];
|
|
2167
|
+
}
|
|
2165
2168
|
function isLocalOrigin(origin) {
|
|
2166
2169
|
if (!origin)
|
|
2167
2170
|
return true;
|