push-sentinel 0.1.0 → 0.1.1

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/bin/cli.js CHANGED
@@ -100,8 +100,9 @@ switch (command) {
100
100
  const localSha = localShaIdx !== -1 ? args[localShaIdx + 1] : undefined;
101
101
  const remoteSha = remoteShaIdx !== -1 ? args[remoteShaIdx + 1] : undefined;
102
102
  const findings = scan(localSha, remoteSha);
103
- report(findings);
104
- if (blockOnHigh && hasHighFindings(findings)) {
103
+ const willBlock = blockOnHigh && hasHighFindings(findings);
104
+ report(findings, { willBlock });
105
+ if (willBlock) {
105
106
  process.stderr.write('\n[push-sentinel] Push blocked: HIGH severity secret(s) detected. Remove the secret or run `push-sentinel ignore` to suppress.\n');
106
107
  process.exit(1);
107
108
  }
package/hook-template.sh CHANGED
@@ -6,10 +6,14 @@
6
6
  #
7
7
  # We read each line and pass the SHAs explicitly so push-sentinel can compute
8
8
  # the exact range of commits being pushed (including new branch / first push).
9
+ # Stdin is saved and re-supplied to pre-push.local so existing hooks still work.
9
10
 
10
11
  EXIT_CODE=0
12
+ STDIN_DATA=""
11
13
 
12
14
  while read local_ref local_sha remote_ref remote_sha; do
15
+ STDIN_DATA="${STDIN_DATA}${local_ref} ${local_sha} ${remote_ref} ${remote_sha}
16
+ "
13
17
  npx push-sentinel scan --local-sha "$local_sha" --remote-sha "$remote_sha"
14
18
  RESULT=$?
15
19
  if [ $RESULT -ne 0 ]; then
@@ -22,5 +26,5 @@ if [ $EXIT_CODE -ne 0 ]; then
22
26
  fi
23
27
 
24
28
  if [ -f "$(git rev-parse --git-dir)/hooks/pre-push.local" ]; then
25
- "$(git rev-parse --git-dir)/hooks/pre-push.local" "$@"
29
+ echo "$STDIN_DATA" | "$(git rev-parse --git-dir)/hooks/pre-push.local" "$@"
26
30
  fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "push-sentinel",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Warns you if secrets are in your git diff before push.",
5
5
  "bin": {
6
6
  "push-sentinel": "bin/cli.js"
package/src/install.js CHANGED
@@ -33,10 +33,14 @@ ${SENTINEL_MARKER}
33
33
  # <local-ref> <local-sha1> <remote-ref> <remote-sha1>
34
34
  # We forward the SHAs so push-sentinel can determine exactly which commits
35
35
  # are being pushed, including new branches (remote-sha = 0000...0000).
36
+ # Stdin is saved and re-supplied to pre-push.local so existing hooks still work.
36
37
 
37
38
  EXIT_CODE=0
39
+ STDIN_DATA=""
38
40
 
39
41
  while read local_ref local_sha remote_ref remote_sha; do
42
+ STDIN_DATA="${'$'}{STDIN_DATA}${'$'}{local_ref} ${'$'}{local_sha} ${'$'}{remote_ref} ${'$'}{remote_sha}
43
+ "
40
44
  npx push-sentinel scan --local-sha "$local_sha" --remote-sha "$remote_sha"
41
45
  RESULT=$?
42
46
  if [ $RESULT -ne 0 ]; then
@@ -49,7 +53,7 @@ if [ $EXIT_CODE -ne 0 ]; then
49
53
  fi
50
54
 
51
55
  if [ -f "$(git rev-parse --git-dir)/hooks/pre-push.local" ]; then
52
- "$(git rev-parse --git-dir)/hooks/pre-push.local" "$@"
56
+ echo "$STDIN_DATA" | "$(git rev-parse --git-dir)/hooks/pre-push.local" "$@"
53
57
  fi
54
58
  `;
55
59
  }
package/src/reporter.js CHANGED
@@ -13,7 +13,7 @@ function severityLabel(severity) {
13
13
  return `[${severity}]`;
14
14
  }
15
15
 
16
- function report(findings) {
16
+ function report(findings, { willBlock = false } = {}) {
17
17
  if (findings.length === 0) {
18
18
  process.stderr.write('[push-sentinel] \u2713 No secrets detected.\n');
19
19
  return;
@@ -39,7 +39,11 @@ function report(findings) {
39
39
  process.stderr.write(` + ${extra} more finding(s) not shown.\n\n`);
40
40
  }
41
41
 
42
- process.stderr.write(' Push continues. Double-check before sharing.\n');
42
+ if (willBlock) {
43
+ process.stderr.write(' Push will be blocked.\n');
44
+ } else {
45
+ process.stderr.write(' Push continues. Double-check before sharing.\n');
46
+ }
43
47
  }
44
48
 
45
49
  function hasHighFindings(findings) {
package/src/scan.js CHANGED
@@ -55,33 +55,31 @@ function loadIgnoreRules(repoRoot) {
55
55
  return { lines, patterns };
56
56
  }
57
57
 
58
+ // Check if a file path matches a single glob-style ignore rule
59
+ function matchesGlob(filePath, rule) {
60
+ if (rule.endsWith('/**')) {
61
+ const dir = rule.slice(0, -3);
62
+ return filePath.startsWith(dir + '/') || filePath === dir;
63
+ }
64
+ if (rule.endsWith('*')) {
65
+ return filePath.startsWith(rule.slice(0, -1));
66
+ }
67
+ return false;
68
+ }
69
+
58
70
  // Check if a file (regardless of line) matches any ignore rule
59
71
  function matchesIgnoreFile(filePath, ignoreLines) {
60
72
  for (const rule of ignoreLines) {
61
- if (rule === filePath) return true;
62
- if (rule.endsWith('/**')) {
63
- const dir = rule.slice(0, -3);
64
- if (filePath.startsWith(dir + '/') || filePath === dir) return true;
65
- }
66
- if (rule.endsWith('*')) {
67
- if (filePath.startsWith(rule.slice(0, -1))) return true;
68
- }
73
+ if (rule === filePath || matchesGlob(filePath, rule)) return true;
69
74
  }
70
75
  return false;
71
76
  }
72
77
 
73
- // Check if a file:line matches any ignore rule (simple glob support)
78
+ // Check if a file:line matches any ignore rule
74
79
  function matchesIgnoreLine(filePath, lineNum, ignoreLines) {
75
80
  const target = `${filePath}:${lineNum}`;
76
81
  for (const rule of ignoreLines) {
77
- if (rule === target) return true;
78
- if (rule.endsWith('/**')) {
79
- const dir = rule.slice(0, -3);
80
- if (filePath.startsWith(dir + '/') || filePath === dir) return true;
81
- }
82
- if (rule.endsWith('*')) {
83
- if (filePath.startsWith(rule.slice(0, -1))) return true;
84
- }
82
+ if (rule === target || matchesGlob(filePath, rule)) return true;
85
83
  }
86
84
  return false;
87
85
  }