@victor-software-house/pi-multicodex 2.1.3 → 2.1.4

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.
@@ -335,7 +335,11 @@ export class AccountManager {
335
335
  if (!imported) return false;
336
336
 
337
337
  const existingImported = this.getImportedAccount();
338
- if (existingImported?.importFingerprint === imported.fingerprint) {
338
+ if (
339
+ existingImported?.importFingerprint === imported.fingerprint &&
340
+ (existingImported.importMode !== "synthetic" ||
341
+ existingImported.email === imported.identifier)
342
+ ) {
339
343
  return false;
340
344
  }
341
345
 
package/auth.ts CHANGED
@@ -45,7 +45,44 @@ function getRequiredString(
45
45
  return typeof value === "string" && value.trim() ? value.trim() : undefined;
46
46
  }
47
47
 
48
- function createImportedIdentifier(accountId: string): string {
48
+ function decodeJwtPayload(token: string): Record<string, unknown> | undefined {
49
+ const parts = token.split(".");
50
+ if (parts.length !== 3) return undefined;
51
+ const payload = parts[1];
52
+ if (!payload) return undefined;
53
+ try {
54
+ const normalized = payload.replace(/-/g, "+").replace(/_/g, "/");
55
+ const padded = normalized.padEnd(
56
+ normalized.length + ((4 - (normalized.length % 4)) % 4),
57
+ "=",
58
+ );
59
+ const decoded = Buffer.from(padded, "base64").toString("utf8");
60
+ const parsed = JSON.parse(decoded) as unknown;
61
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
62
+ return undefined;
63
+ }
64
+ return parsed as Record<string, unknown>;
65
+ } catch {
66
+ return undefined;
67
+ }
68
+ }
69
+
70
+ function getProfileEmail(accessToken: string): string | undefined {
71
+ const payload = decodeJwtPayload(accessToken);
72
+ const profile = payload?.["https://api.openai.com/profile"];
73
+ if (!profile || typeof profile !== "object" || Array.isArray(profile)) {
74
+ return undefined;
75
+ }
76
+ const email = (profile as Record<string, unknown>).email;
77
+ return typeof email === "string" && email.trim() ? email.trim() : undefined;
78
+ }
79
+
80
+ function createImportedIdentifier(
81
+ accessToken: string,
82
+ accountId: string,
83
+ ): string {
84
+ const email = getProfileEmail(accessToken);
85
+ if (email) return email;
49
86
  return `${IMPORTED_ACCOUNT_PREFIX} ${accountId.slice(0, 8)}`;
50
87
  }
51
88
 
@@ -84,7 +121,7 @@ export function parseImportedOpenAICodexAuth(
84
121
  accountId,
85
122
  };
86
123
  return {
87
- identifier: createImportedIdentifier(accountId ?? "default"),
124
+ identifier: createImportedIdentifier(access, accountId ?? "default"),
88
125
  fingerprint: createFingerprint({ access, refresh, expires, accountId }),
89
126
  credentials,
90
127
  };
package/commands.ts CHANGED
@@ -99,7 +99,7 @@ function formatAccountStatusLine(
99
99
  const quotaHit =
100
100
  account.quotaExhaustedUntil && account.quotaExhaustedUntil > Date.now();
101
101
  const untouched = isUsageUntouched(usage) ? "untouched" : null;
102
- const imported = account.importSource ? "linked-auth" : null;
102
+ const imported = account.importSource ? "pi auth" : null;
103
103
  const reauth = account.needsReauth ? "needs reauth" : null;
104
104
  const tags = [
105
105
  active?.email === account.email ? "active" : null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@victor-software-house/pi-multicodex",
3
- "version": "2.1.3",
3
+ "version": "2.1.4",
4
4
  "description": "Codex account rotation extension for pi",
5
5
  "license": "MIT",
6
6
  "type": "module",