@app-vitals/agent-admin 1.15.0 → 1.17.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.
@@ -0,0 +1,20 @@
1
+ /**
2
+ * GHE-2.1: GitHub login syntax validation. Syntax only — never calls GitHub.
3
+ * A login is 1-39 chars of alphanumerics and single hyphens, with no leading
4
+ * or trailing hyphen (consecutive hyphens are invalid).
5
+ */
6
+ const GITHUB_LOGIN_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/i;
7
+ const GITHUB_LOGIN_MAX_LENGTH = 39;
8
+
9
+ export function isValidGithubUsername(value: string): boolean {
10
+ return (
11
+ value.length > 0 &&
12
+ value.length <= GITHUB_LOGIN_MAX_LENGTH &&
13
+ GITHUB_LOGIN_PATTERN.test(value)
14
+ );
15
+ }
16
+
17
+ /** Returns the lower-cased login, or null when the syntax is invalid. */
18
+ export function normalizeGithubUsername(value: string): string | null {
19
+ return isValidGithubUsername(value) ? value.toLowerCase() : null;
20
+ }
@@ -0,0 +1,34 @@
1
+ import { describe, expect, it } from "bun:test";
2
+ import {
3
+ isValidGithubUsername,
4
+ normalizeGithubUsername,
5
+ } from "./github-username.ts";
6
+
7
+ describe("github username syntax (GHE-2.1)", () => {
8
+ it("accepts valid logins", () => {
9
+ for (const ok of [
10
+ "a",
11
+ "octocat",
12
+ "Octo-Cat",
13
+ "a-b-c",
14
+ "a1",
15
+ "a".repeat(39),
16
+ ])
17
+ expect(isValidGithubUsername(ok)).toBe(true);
18
+ });
19
+
20
+ it("rejects leading/trailing/consecutive hyphens", () => {
21
+ for (const bad of ["-a", "a-", "a--b", "-"])
22
+ expect(isValidGithubUsername(bad)).toBe(false);
23
+ });
24
+
25
+ it("rejects too long, empty and illegal characters", () => {
26
+ for (const bad of ["a".repeat(40), "", "a_b", "a b", "a.b", "é"])
27
+ expect(isValidGithubUsername(bad)).toBe(false);
28
+ });
29
+
30
+ it("normalize lower-cases valid input and returns null otherwise", () => {
31
+ expect(normalizeGithubUsername("Octo-Cat")).toBe("octo-cat");
32
+ expect(normalizeGithubUsername("-bad")).toBeNull();
33
+ });
34
+ });
@@ -114,6 +114,16 @@ export const PatchAgentBodySchema = z
114
114
  .nullable()
115
115
  .optional()
116
116
  .openapi({ example: "agent-pod-sa" }),
117
+ /**
118
+ * GHE-2.1: GitHub account whose repo access caps the agent (cap applied
119
+ * later). Platform admin only; `null` clears it. Lower-cased on save;
120
+ * syntax-checked (422) with no GitHub call.
121
+ */
122
+ githubUsername: z
123
+ .string()
124
+ .nullable()
125
+ .optional()
126
+ .openapi({ example: "octocat" }),
117
127
  /**
118
128
  * ATE-1.1: trial expiry timestamp. Nullable so it can also be explicitly
119
129
  * cleared. trialExpiryWarnedAt is intentionally NOT part of this schema —