@h-rig/server 0.0.6-alpha.0 → 0.0.6-alpha.10

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.
@@ -1,5 +1,6 @@
1
1
  // @bun
2
2
  // packages/server/src/server-helpers/github-auth-store.ts
3
+ import { randomBytes } from "crypto";
3
4
  import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
4
5
  import { resolve as resolve2 } from "path";
5
6
 
@@ -39,6 +40,24 @@ function cleanScopes(value) {
39
40
  return clean ? [clean] : [];
40
41
  });
41
42
  }
43
+ function parseApiSessions(value) {
44
+ if (!Array.isArray(value))
45
+ return [];
46
+ return value.flatMap((entry) => {
47
+ if (!entry || typeof entry !== "object" || Array.isArray(entry))
48
+ return [];
49
+ const record = entry;
50
+ const token = cleanString(record.token);
51
+ if (!token)
52
+ return [];
53
+ return [{
54
+ token,
55
+ login: cleanString(record.login),
56
+ userId: cleanString(record.userId),
57
+ createdAt: cleanString(record.createdAt) ?? undefined
58
+ }];
59
+ });
60
+ }
42
61
  function readStoredAuth(stateFile) {
43
62
  if (!existsSync(stateFile))
44
63
  return {};
@@ -52,6 +71,7 @@ function readStoredAuth(stateFile) {
52
71
  selectedRepo: cleanString(parsed.selectedRepo),
53
72
  tokenSource: parsed.tokenSource === "oauth-device" || parsed.tokenSource === "manual-token" || parsed.tokenSource === "env" ? parsed.tokenSource : undefined,
54
73
  pendingDevice: parsePendingDevice(parsed.pendingDevice),
74
+ apiSessions: parseApiSessions(parsed.apiSessions),
55
75
  updatedAt: cleanString(parsed.updatedAt) ?? undefined
56
76
  };
57
77
  } catch {
@@ -70,6 +90,9 @@ function parsePendingDevice(value) {
70
90
  return null;
71
91
  return { pollId, deviceCode, expiresAt, intervalSeconds };
72
92
  }
93
+ function newApiSessionToken() {
94
+ return `rig_${randomBytes(32).toString("base64url")}`;
95
+ }
73
96
  function writeStoredAuth(stateFile, payload) {
74
97
  mkdirSync(resolve2(stateFile, ".."), { recursive: true });
75
98
  writeFileSync(stateFile, `${JSON.stringify(payload, null, 2)}
@@ -112,9 +135,38 @@ function createGitHubAuthStore(projectRoot) {
112
135
  scopes: input.scopes ?? [],
113
136
  selectedRepo: input.selectedRepo ?? previous.selectedRepo ?? null,
114
137
  pendingDevice: null,
138
+ apiSessions: previous.apiSessions ?? [],
115
139
  updatedAt: new Date().toISOString()
116
140
  });
117
141
  },
142
+ createApiSession() {
143
+ const previous = readStoredAuth(stateFile);
144
+ const token = newApiSessionToken();
145
+ const session = {
146
+ token,
147
+ login: cleanString(previous.login),
148
+ userId: cleanString(previous.userId),
149
+ createdAt: new Date().toISOString()
150
+ };
151
+ writeStoredAuth(stateFile, {
152
+ ...previous,
153
+ apiSessions: [...(previous.apiSessions ?? []).slice(-9), session],
154
+ updatedAt: new Date().toISOString()
155
+ });
156
+ return { token, login: session.login ?? null, userId: session.userId ?? null };
157
+ },
158
+ readApiSession(token) {
159
+ const clean = cleanString(token);
160
+ if (!clean)
161
+ return null;
162
+ const previous = readStoredAuth(stateFile);
163
+ const session = (previous.apiSessions ?? []).find((candidate) => candidate.token === clean);
164
+ return session ? { login: cleanString(session.login), userId: cleanString(session.userId) } : null;
165
+ },
166
+ copyToProjectRoot(projectRoot2) {
167
+ const targetFile = resolveGitHubAuthStateFile(projectRoot2);
168
+ writeStoredAuth(targetFile, readStoredAuth(stateFile));
169
+ },
118
170
  savePendingDevice(input) {
119
171
  const previous = readStoredAuth(stateFile);
120
172
  writeStoredAuth(stateFile, {