auditreach-cli 0.1.0

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.
Files changed (55) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +233 -0
  3. package/dist/audit-log/chain-verifier.d.ts +9 -0
  4. package/dist/audit-log/chain-verifier.d.ts.map +1 -0
  5. package/dist/audit-log/chain-verifier.js +79 -0
  6. package/dist/audit-log/chain-verifier.js.map +1 -0
  7. package/dist/audit-log/hash-chain-writer.d.ts +16 -0
  8. package/dist/audit-log/hash-chain-writer.d.ts.map +1 -0
  9. package/dist/audit-log/hash-chain-writer.js +49 -0
  10. package/dist/audit-log/hash-chain-writer.js.map +1 -0
  11. package/dist/auth/credential-store.d.ts +24 -0
  12. package/dist/auth/credential-store.d.ts.map +1 -0
  13. package/dist/auth/credential-store.js +50 -0
  14. package/dist/auth/credential-store.js.map +1 -0
  15. package/dist/cli.d.ts +3 -0
  16. package/dist/cli.d.ts.map +1 -0
  17. package/dist/cli.js +74 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/clients/reddit-client.d.ts +33 -0
  20. package/dist/clients/reddit-client.d.ts.map +1 -0
  21. package/dist/clients/reddit-client.js +153 -0
  22. package/dist/clients/reddit-client.js.map +1 -0
  23. package/dist/clients/youtube-client.d.ts +16 -0
  24. package/dist/clients/youtube-client.d.ts.map +1 -0
  25. package/dist/clients/youtube-client.js +77 -0
  26. package/dist/clients/youtube-client.js.map +1 -0
  27. package/dist/commands/auth.d.ts +8 -0
  28. package/dist/commands/auth.d.ts.map +1 -0
  29. package/dist/commands/auth.js +90 -0
  30. package/dist/commands/auth.js.map +1 -0
  31. package/dist/commands/search.d.ts +14 -0
  32. package/dist/commands/search.d.ts.map +1 -0
  33. package/dist/commands/search.js +112 -0
  34. package/dist/commands/search.js.map +1 -0
  35. package/dist/commands/verify-log.d.ts +5 -0
  36. package/dist/commands/verify-log.d.ts.map +1 -0
  37. package/dist/commands/verify-log.js +19 -0
  38. package/dist/commands/verify-log.js.map +1 -0
  39. package/dist/index.d.ts +8 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +7 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/types.d.ts +62 -0
  44. package/dist/types.d.ts.map +1 -0
  45. package/dist/types.js +2 -0
  46. package/dist/types.js.map +1 -0
  47. package/dist/util/crypto.d.ts +16 -0
  48. package/dist/util/crypto.d.ts.map +1 -0
  49. package/dist/util/crypto.js +40 -0
  50. package/dist/util/crypto.js.map +1 -0
  51. package/dist/util/prompt.d.ts +11 -0
  52. package/dist/util/prompt.d.ts.map +1 -0
  53. package/dist/util/prompt.js +67 -0
  54. package/dist/util/prompt.js.map +1 -0
  55. package/package.json +62 -0
@@ -0,0 +1,112 @@
1
+ import { writeFile } from "node:fs/promises";
2
+ import { RedditClient, MAX_LIMIT as REDDIT_MAX_LIMIT } from "../clients/reddit-client.js";
3
+ import { YoutubeClient, MAX_MAX_RESULTS as YOUTUBE_MAX_MAX_RESULTS, } from "../clients/youtube-client.js";
4
+ import { getRedditCredentials, getYoutubeCredentials } from "../auth/credential-store.js";
5
+ import { appendAuditLogEntry, getLastEntryHash } from "../audit-log/hash-chain-writer.js";
6
+ import { credentialFingerprint, generateEntryId } from "../util/crypto.js";
7
+ export async function runSearchCommand(args) {
8
+ let outcome;
9
+ let fingerprintSource;
10
+ if (args.platform === "reddit") {
11
+ const credentials = getRedditCredentials();
12
+ if (!credentials) {
13
+ console.error('No Reddit credentials found. Run "auditreach auth --platform reddit" first.');
14
+ process.exitCode = 1;
15
+ return;
16
+ }
17
+ if (!args.query) {
18
+ console.error('Reddit search requires --query "<search terms>".');
19
+ process.exitCode = 1;
20
+ return;
21
+ }
22
+ const client = new RedditClient(credentials);
23
+ outcome = await client.search({
24
+ query: args.query,
25
+ subreddit: args.subreddit,
26
+ limit: args.maxResults,
27
+ before: args.before,
28
+ after: args.after,
29
+ });
30
+ fingerprintSource = credentials.clientSecret;
31
+ }
32
+ else {
33
+ const credentials = getYoutubeCredentials();
34
+ if (!credentials) {
35
+ console.error('No YouTube credentials found. Run "auditreach auth --platform youtube" first.');
36
+ process.exitCode = 1;
37
+ return;
38
+ }
39
+ const client = new YoutubeClient(credentials);
40
+ outcome = await client.search({
41
+ query: args.query,
42
+ channelHandle: args.channel,
43
+ since: args.since,
44
+ maxResults: args.maxResults,
45
+ });
46
+ fingerprintSource = credentials.apiKey;
47
+ }
48
+ printResults(outcome);
49
+ const outputPath = args.output ?? defaultOutputPath();
50
+ await writeFile(outputPath, JSON.stringify(outcome.items, null, 2), "utf8");
51
+ const prevHash = await getLastEntryHash();
52
+ const entry = await appendAuditLogEntry({
53
+ entry_id: generateEntryId(),
54
+ timestamp: new Date().toISOString(),
55
+ platform: outcome.platform,
56
+ endpoint: outcome.endpoint,
57
+ query_params: outcome.queryParams,
58
+ auth_scope: outcome.authScope,
59
+ consent_basis: outcome.consentBasis,
60
+ api_key_fingerprint: `sha256:${credentialFingerprint(fingerprintSource)}`,
61
+ results_returned: outcome.items.length,
62
+ prev_entry_hash: prevHash,
63
+ });
64
+ console.log(`\nAudit log entry written: ${entry.entry_id}`);
65
+ console.log(`Consent basis: ${entry.consent_basis}`);
66
+ console.log(`Full results: ${outputPath}`);
67
+ console.log(`Full audit trail: ./auditreach.log.jsonl`);
68
+ }
69
+ function defaultOutputPath() {
70
+ const date = new Date().toISOString().slice(0, 10);
71
+ return `./auditreach-results-${date}.json`;
72
+ }
73
+ function printResults(outcome) {
74
+ console.log(`\nAuditReach v0.1 -- Official-API Research CLI`);
75
+ console.log(`Platform: ${capitalize(outcome.platform)} | Auth: ${outcome.authScope}`);
76
+ console.log(`\nFetching... (official API, rate-limit aware)`);
77
+ console.log(`✓ ${outcome.items.length} results returned (${outcome.consentBasis})\n`);
78
+ console.log(`RESULTS (${outcome.items.length})`);
79
+ outcome.items.slice(0, 10).forEach((item, i) => {
80
+ console.log(`[${i + 1}] "${item.title}"`);
81
+ console.log(` ${item.author ?? "unknown"} · ${item.createdAt}`);
82
+ console.log(` ${item.url}`);
83
+ });
84
+ if (outcome.items.length > 10) {
85
+ console.log(`... and ${outcome.items.length - 10} more (see output file)`);
86
+ }
87
+ if (outcome.nextCursor?.after) {
88
+ console.log(`\nNext page: rerun with --after ${outcome.nextCursor.after}`);
89
+ }
90
+ if (outcome.nextCursor?.before) {
91
+ console.log(`Previous page: rerun with --before ${outcome.nextCursor.before}`);
92
+ }
93
+ warnIfTruncated(outcome);
94
+ }
95
+ function warnIfTruncated(outcome) {
96
+ const appliedLimit = outcome.platform === "reddit" ? outcome.queryParams.limit : outcome.queryParams.maxResults;
97
+ if (typeof appliedLimit !== "number" || outcome.items.length < appliedLimit) {
98
+ return;
99
+ }
100
+ const cap = outcome.platform === "reddit" ? REDDIT_MAX_LIMIT : YOUTUBE_MAX_MAX_RESULTS;
101
+ const platformName = capitalize(outcome.platform);
102
+ if (appliedLimit < cap) {
103
+ console.error(`\nWarning: returned exactly ${outcome.items.length} results, the limit applied for this search -- more results may exist. Pass --max-results <n> (up to ${cap} for ${platformName}) to request more.`);
104
+ }
105
+ else {
106
+ console.error(`\nWarning: returned exactly ${outcome.items.length} results, ${platformName}'s per-request maximum -- more results may exist beyond what a single search call can return.`);
107
+ }
108
+ }
109
+ function capitalize(value) {
110
+ return value.charAt(0).toUpperCase() + value.slice(1);
111
+ }
112
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export interface VerifyLogCommandArgs {
2
+ path?: string;
3
+ }
4
+ export declare function runVerifyLogCommand(args: VerifyLogCommandArgs): Promise<void>;
5
+ //# sourceMappingURL=verify-log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-log.d.ts","sourceRoot":"","sources":["../../src/commands/verify-log.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBnF"}
@@ -0,0 +1,19 @@
1
+ import { verifyAuditLogChain } from "../audit-log/chain-verifier.js";
2
+ import { DEFAULT_AUDIT_LOG_PATH } from "../audit-log/hash-chain-writer.js";
3
+ export async function runVerifyLogCommand(args) {
4
+ const logPath = args.path ?? DEFAULT_AUDIT_LOG_PATH;
5
+ console.log(`Verifying ${logPath}...`);
6
+ const result = await verifyAuditLogChain(logPath);
7
+ if (result.totalEntries === 0) {
8
+ console.log("No entries yet -- nothing to verify.");
9
+ return;
10
+ }
11
+ if (result.valid) {
12
+ console.log(`✓ Chain intact: ${result.totalEntries} entries, no gaps, no tampering detected.`);
13
+ }
14
+ else {
15
+ console.error(`✗ Chain broken at entry ${result.brokenAtIndex} (${result.brokenAtEntryId ?? "unknown"}): ${result.reason}`);
16
+ process.exitCode = 1;
17
+ }
18
+ }
19
+ //# sourceMappingURL=verify-log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-log.js","sourceRoot":"","sources":["../../src/commands/verify-log.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAM3E,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAA0B;IAClE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,sBAAsB,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,aAAa,OAAO,KAAK,CAAC,CAAC;IAEvC,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAElD,IAAI,MAAM,CAAC,YAAY,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,CAAC,YAAY,2CAA2C,CAAC,CAAC;IACjG,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CACX,2BAA2B,MAAM,CAAC,aAAa,KAAK,MAAM,CAAC,eAAe,IAAI,SAAS,MAAM,MAAM,CAAC,MAAM,EAAE,CAC7G,CAAC;QACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ export { RedditClient } from "./clients/reddit-client.js";
2
+ export { YoutubeClient } from "./clients/youtube-client.js";
3
+ export { getCredential, setCredential, deleteCredential, getRedditCredentials, getYoutubeCredentials, } from "./auth/credential-store.js";
4
+ export { appendAuditLogEntry, getLastEntryHash, computeEntryHash, DEFAULT_AUDIT_LOG_PATH, } from "./audit-log/hash-chain-writer.js";
5
+ export { verifyAuditLogChain } from "./audit-log/chain-verifier.js";
6
+ export { credentialFingerprint, canonicalJson, sha256Hex } from "./util/crypto.js";
7
+ export type { Platform, AuditLogEntry, UnhashedAuditLogEntry, ChainVerificationResult, SearchResultItem, SearchOutcome, RedditSearchOptions, YoutubeSearchOptions, } from "./types.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EACL,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACnF,YAAY,EACV,QAAQ,EACR,aAAa,EACb,qBAAqB,EACrB,uBAAuB,EACvB,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { RedditClient } from "./clients/reddit-client.js";
2
+ export { YoutubeClient } from "./clients/youtube-client.js";
3
+ export { getCredential, setCredential, deleteCredential, getRedditCredentials, getYoutubeCredentials, } from "./auth/credential-store.js";
4
+ export { appendAuditLogEntry, getLastEntryHash, computeEntryHash, DEFAULT_AUDIT_LOG_PATH, } from "./audit-log/hash-chain-writer.js";
5
+ export { verifyAuditLogChain } from "./audit-log/chain-verifier.js";
6
+ export { credentialFingerprint, canonicalJson, sha256Hex } from "./util/crypto.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EACL,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,62 @@
1
+ export type Platform = "reddit" | "youtube";
2
+ export interface AuditLogEntry {
3
+ entry_id: string;
4
+ timestamp: string;
5
+ platform: Platform;
6
+ endpoint: string;
7
+ query_params: Record<string, string | number | boolean | undefined>;
8
+ auth_scope: string;
9
+ consent_basis: string;
10
+ api_key_fingerprint: string;
11
+ results_returned: number;
12
+ prev_entry_hash: string | null;
13
+ entry_hash: string;
14
+ }
15
+ export type UnhashedAuditLogEntry = Omit<AuditLogEntry, "entry_hash">;
16
+ export interface ChainVerificationResult {
17
+ valid: boolean;
18
+ totalEntries: number;
19
+ brokenAtEntryId: string | null;
20
+ brokenAtIndex: number | null;
21
+ reason: string | null;
22
+ }
23
+ export interface SearchResultItem {
24
+ id: string;
25
+ title: string;
26
+ url: string;
27
+ createdAt: string;
28
+ author: string | null;
29
+ score: number | null;
30
+ extra: Record<string, unknown>;
31
+ }
32
+ /** Cursor fullnames read back from a platform's response, for requesting the next/previous page. */
33
+ export interface SearchCursor {
34
+ after: string | null;
35
+ before: string | null;
36
+ }
37
+ export interface SearchOutcome {
38
+ platform: Platform;
39
+ endpoint: string;
40
+ queryParams: Record<string, string | number | boolean | undefined>;
41
+ authScope: string;
42
+ consentBasis: string;
43
+ items: SearchResultItem[];
44
+ /** Pagination cursors extracted from the response itself (not an echo of the request params). Populated when the platform's API exposes them. */
45
+ nextCursor?: SearchCursor;
46
+ }
47
+ export interface RedditSearchOptions {
48
+ query: string;
49
+ subreddit?: string;
50
+ limit?: number;
51
+ /** Reddit fullname (e.g. "t3_abc123") to page results before, for paginating past the ~1000-result search cap. */
52
+ before?: string;
53
+ /** Reddit fullname (e.g. "t3_abc123") to page results after, for paginating past the ~1000-result search cap. */
54
+ after?: string;
55
+ }
56
+ export interface YoutubeSearchOptions {
57
+ query?: string;
58
+ channelHandle?: string;
59
+ since?: string;
60
+ maxResults?: number;
61
+ }
62
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE5C,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;IACpE,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;AAEtE,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,OAAO,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,oGAAoG;AACpG,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;IACnE,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,iJAAiJ;IACjJ,UAAU,CAAC,EAAE,YAAY,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kHAAkH;IAClH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iHAAiH;IACjH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Canonical JSON: sorts object keys recursively so the same logical entry
3
+ * always serializes to the same bytes, regardless of insertion order. This
4
+ * is required for the audit-log hash chain to verify deterministically.
5
+ */
6
+ export declare function canonicalJson(value: unknown): string;
7
+ export declare function sha256Hex(input: string): string;
8
+ /**
9
+ * A fingerprint proves which credential made a query without ever storing
10
+ * or logging the credential itself. Only the last 6 hex characters of the
11
+ * hash are kept -- enough to distinguish rotated keys in a local audit log,
12
+ * not enough to be a partial credential leak.
13
+ */
14
+ export declare function credentialFingerprint(secret: string): string;
15
+ export declare function generateEntryId(prefix?: string): string;
16
+ //# sourceMappingURL=crypto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/util/crypto.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEpD;AAgBD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,eAAe,CAAC,MAAM,SAAO,GAAG,MAAM,CAIrD"}
@@ -0,0 +1,40 @@
1
+ import { createHash, randomBytes } from "node:crypto";
2
+ /**
3
+ * Canonical JSON: sorts object keys recursively so the same logical entry
4
+ * always serializes to the same bytes, regardless of insertion order. This
5
+ * is required for the audit-log hash chain to verify deterministically.
6
+ */
7
+ export function canonicalJson(value) {
8
+ return JSON.stringify(sortKeysDeep(value));
9
+ }
10
+ function sortKeysDeep(value) {
11
+ if (Array.isArray(value)) {
12
+ return value.map(sortKeysDeep);
13
+ }
14
+ if (value !== null && typeof value === "object") {
15
+ const sorted = {};
16
+ for (const key of Object.keys(value).sort()) {
17
+ sorted[key] = sortKeysDeep(value[key]);
18
+ }
19
+ return sorted;
20
+ }
21
+ return value;
22
+ }
23
+ export function sha256Hex(input) {
24
+ return createHash("sha256").update(input, "utf8").digest("hex");
25
+ }
26
+ /**
27
+ * A fingerprint proves which credential made a query without ever storing
28
+ * or logging the credential itself. Only the last 6 hex characters of the
29
+ * hash are kept -- enough to distinguish rotated keys in a local audit log,
30
+ * not enough to be a partial credential leak.
31
+ */
32
+ export function credentialFingerprint(secret) {
33
+ return sha256Hex(secret).slice(-6);
34
+ }
35
+ export function generateEntryId(prefix = "ar") {
36
+ const date = new Date().toISOString().slice(0, 10);
37
+ const rand = randomBytes(3).toString("hex");
38
+ return `${prefix}_${date}_${rand}`;
39
+ }
40
+ //# sourceMappingURL=crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/util/crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEtD;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAgC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YACvE,MAAM,CAAC,GAAG,CAAC,GAAG,YAAY,CAAE,KAAiC,CAAC,GAAG,CAAC,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAClE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAc;IAClD,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAM,GAAG,IAAI;IAC3C,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACnD,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5C,OAAO,GAAG,MAAM,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;AACrC,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Prompts for a plain-text value (non-secret). Echoes normally.
3
+ */
4
+ export declare function promptText(question: string): Promise<string>;
5
+ /**
6
+ * Prompts for a secret value (API key, client secret, password) without
7
+ * echoing it back to the terminal -- masks each keystroke as it's typed
8
+ * so a secret never appears in scrollback or a screen-share.
9
+ */
10
+ export declare function promptSecret(question: string): Promise<string>;
11
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/util/prompt.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ5D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgD9D"}
@@ -0,0 +1,67 @@
1
+ import { createInterface } from "node:readline";
2
+ const CTRL_C = String.fromCharCode(3);
3
+ const BACKSPACE_DEL = String.fromCharCode(127);
4
+ const BACKSPACE_BS = String.fromCharCode(8);
5
+ /**
6
+ * Prompts for a plain-text value (non-secret). Echoes normally.
7
+ */
8
+ export function promptText(question) {
9
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
10
+ return new Promise((resolve) => {
11
+ rl.question(question, (answer) => {
12
+ rl.close();
13
+ resolve(answer.trim());
14
+ });
15
+ });
16
+ }
17
+ /**
18
+ * Prompts for a secret value (API key, client secret, password) without
19
+ * echoing it back to the terminal -- masks each keystroke as it's typed
20
+ * so a secret never appears in scrollback or a screen-share.
21
+ */
22
+ export function promptSecret(question) {
23
+ return new Promise((resolve) => {
24
+ process.stdout.write(question);
25
+ const stdin = process.stdin;
26
+ const wasRaw = stdin.isRaw;
27
+ let value = "";
28
+ if (stdin.isTTY) {
29
+ stdin.setRawMode(true);
30
+ }
31
+ stdin.resume();
32
+ stdin.setEncoding("utf8");
33
+ const cleanup = () => {
34
+ stdin.removeListener("data", onData);
35
+ if (stdin.isTTY) {
36
+ stdin.setRawMode(wasRaw ?? false);
37
+ }
38
+ stdin.pause();
39
+ };
40
+ const onData = (chunk) => {
41
+ for (const char of chunk) {
42
+ if (char === "\n" || char === "\r") {
43
+ cleanup();
44
+ process.stdout.write("\n");
45
+ resolve(value);
46
+ return;
47
+ }
48
+ if (char === CTRL_C) {
49
+ cleanup();
50
+ process.stdout.write("\n");
51
+ process.exit(130);
52
+ }
53
+ if (char === BACKSPACE_DEL || char === BACKSPACE_BS) {
54
+ if (value.length > 0) {
55
+ value = value.slice(0, -1);
56
+ process.stdout.write("\b \b");
57
+ }
58
+ continue;
59
+ }
60
+ value += char;
61
+ process.stdout.write("*");
62
+ }
63
+ };
64
+ stdin.on("data", onData);
65
+ });
66
+ }
67
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/util/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AACtC,MAAM,aAAa,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AAE5C;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE;YAC/B,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC5B,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC;QAC3B,IAAI,KAAK,GAAG,EAAE,CAAC;QAEf,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;QACD,KAAK,CAAC,MAAM,EAAE,CAAC;QACf,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAE1B,MAAM,OAAO,GAAG,GAAS,EAAE;YACzB,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACrC,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAChB,KAAK,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;YACpC,CAAC;YACD,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,CAAC,KAAa,EAAQ,EAAE;YACrC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;oBACnC,OAAO,EAAE,CAAC;oBACV,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC3B,OAAO,CAAC,KAAK,CAAC,CAAC;oBACf,OAAO;gBACT,CAAC;gBACD,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;oBACpB,OAAO,EAAE,CAAC;oBACV,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC3B,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACpB,CAAC;gBACD,IAAI,IAAI,KAAK,aAAa,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;oBACpD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACrB,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;wBAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;oBAChC,CAAC;oBACD,SAAS;gBACX,CAAC;gBACD,KAAK,IAAI,IAAI,CAAC;gBACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC,CAAC;QAEF,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;AACL,CAAC"}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "auditreach-cli",
3
+ "version": "0.1.0",
4
+ "description": "Official-API-only, BYOK research CLI with a hash-chained compliance audit log -- for AI agents that can't legally use cookie-based scraping",
5
+ "type": "module",
6
+ "bin": {
7
+ "auditreach": "./dist/cli.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "engines": {
15
+ "node": ">=20"
16
+ },
17
+ "scripts": {
18
+ "build": "tsc -p tsconfig.json",
19
+ "dev": "tsx src/cli.ts",
20
+ "lint": "eslint .",
21
+ "format": "prettier --check .",
22
+ "format:fix": "prettier --write .",
23
+ "typecheck": "tsc --noEmit --strict",
24
+ "test": "vitest run",
25
+ "test:coverage": "vitest run --coverage",
26
+ "prepublishOnly": "npm run build"
27
+ },
28
+ "keywords": [
29
+ "cli",
30
+ "byok",
31
+ "compliance",
32
+ "audit-log",
33
+ "reddit-api",
34
+ "youtube-api",
35
+ "ai-agent",
36
+ "research"
37
+ ],
38
+ "author": "Rudrendu Paul",
39
+ "license": "Apache-2.0",
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "git+https://github.com/RudrenduPaul/auditreach.git"
43
+ },
44
+ "dependencies": {
45
+ "@napi-rs/keyring": "^1.3.0",
46
+ "commander": "^12.1.0",
47
+ "googleapis": "^173.0.0"
48
+ },
49
+ "devDependencies": {
50
+ "@eslint/js": "^9.17.0",
51
+ "@types/node": "^22.10.2",
52
+ "@typescript-eslint/eslint-plugin": "^8.19.1",
53
+ "@typescript-eslint/parser": "^8.19.1",
54
+ "@vitest/coverage-v8": "^4.1.10",
55
+ "eslint": "^9.17.0",
56
+ "globals": "^15.15.0",
57
+ "prettier": "^3.4.2",
58
+ "tsx": "^4.19.2",
59
+ "typescript": "^5.7.2",
60
+ "vitest": "^4.1.10"
61
+ }
62
+ }