@agentxm/registry-auth 0.28.4-bootstrap.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.
- package/LICENSE +110 -0
- package/dist/src/auth-client.d.ts +199 -0
- package/dist/src/auth-client.js +638 -0
- package/dist/src/auth-middleware.d.ts +28 -0
- package/dist/src/auth-middleware.js +105 -0
- package/dist/src/credential-store.d.ts +77 -0
- package/dist/src/credential-store.js +443 -0
- package/dist/src/device-login.d.ts +114 -0
- package/dist/src/device-login.js +300 -0
- package/dist/src/errors.d.ts +141 -0
- package/dist/src/errors.js +84 -0
- package/dist/src/guard.d.ts +24 -0
- package/dist/src/guard.js +62 -0
- package/dist/src/index.d.ts +36 -0
- package/dist/src/index.js +31 -0
- package/dist/src/internal/environment.d.ts +23 -0
- package/dist/src/internal/environment.js +45 -0
- package/dist/src/live.d.ts +13 -0
- package/dist/src/live.js +13 -0
- package/dist/src/login-interaction.d.ts +41 -0
- package/dist/src/login-interaction.js +108 -0
- package/dist/src/login-output.d.ts +22 -0
- package/dist/src/login-output.js +32 -0
- package/dist/src/login-presenter.d.ts +95 -0
- package/dist/src/login-presenter.js +58 -0
- package/dist/src/login-strategy.d.ts +21 -0
- package/dist/src/login-strategy.js +25 -0
- package/dist/src/loopback-login.d.ts +19 -0
- package/dist/src/loopback-login.js +91 -0
- package/dist/src/loopback-server.d.ts +40 -0
- package/dist/src/loopback-server.js +168 -0
- package/dist/src/oauth-contract.d.ts +7 -0
- package/dist/src/oauth-contract.js +2 -0
- package/dist/src/pending-device-login-store.d.ts +37 -0
- package/dist/src/pending-device-login-store.js +122 -0
- package/dist/src/publish-authorization.d.ts +11 -0
- package/dist/src/publish-authorization.js +79 -0
- package/dist/src/schema.d.ts +78 -0
- package/dist/src/schema.js +55 -0
- package/dist/src/testing.d.ts +14 -0
- package/dist/src/testing.js +14 -0
- package/dist/src/token-resolution.d.ts +79 -0
- package/dist/src/token-resolution.js +190 -0
- package/package.json +62 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema definitions for credential storage and token sources.
|
|
3
|
+
*
|
|
4
|
+
* @experimental This API is unstable and may change without notice.
|
|
5
|
+
*/
|
|
6
|
+
import * as Data from "effect/Data";
|
|
7
|
+
import * as Schema from "effect/Schema";
|
|
8
|
+
import { DateTimeUtcSchema } from "@agentxm/extension-model/unstable/date-time";
|
|
9
|
+
import { HandleSchema } from "@agentxm/extension-model/unstable/extensions/handle";
|
|
10
|
+
// -----------------------------------------------------------------------------
|
|
11
|
+
// Credential Entry
|
|
12
|
+
// -----------------------------------------------------------------------------
|
|
13
|
+
export const CredentialEntrySchema = Schema.Struct({
|
|
14
|
+
access_token: Schema.String.pipe(Schema.annotateKey({ messageMissingKey: "access_token is required" })),
|
|
15
|
+
refresh_token: Schema.String.pipe(Schema.annotateKey({ messageMissingKey: "refresh_token is required" })),
|
|
16
|
+
expires_at: DateTimeUtcSchema.pipe(Schema.annotateKey({ messageMissingKey: "expires_at is required" })),
|
|
17
|
+
active: Schema.Boolean.pipe(Schema.annotateKey({ messageMissingKey: "active is required" })),
|
|
18
|
+
}).annotate({
|
|
19
|
+
identifier: "CredentialEntry",
|
|
20
|
+
title: "Credential Entry",
|
|
21
|
+
description: "A saved login credential with access token, refresh token, and expiration time.",
|
|
22
|
+
});
|
|
23
|
+
// -----------------------------------------------------------------------------
|
|
24
|
+
// Registry Accounts
|
|
25
|
+
// -----------------------------------------------------------------------------
|
|
26
|
+
export const RegistryAccountsSchema = Schema.Struct({
|
|
27
|
+
accounts: Schema.Record(HandleSchema, CredentialEntrySchema).pipe(Schema.annotateKey({ messageMissingKey: "accounts is required" })),
|
|
28
|
+
}).annotate({
|
|
29
|
+
identifier: "RegistryAccounts",
|
|
30
|
+
title: "Registry Accounts",
|
|
31
|
+
description: "Accounts you're logged into on a registry, keyed by handle.",
|
|
32
|
+
});
|
|
33
|
+
// -----------------------------------------------------------------------------
|
|
34
|
+
// Credential File (versioned, keyed by registry URL)
|
|
35
|
+
// -----------------------------------------------------------------------------
|
|
36
|
+
export const CredentialFileSchema = Schema.Struct({
|
|
37
|
+
version: Schema.Literal(1).pipe(Schema.annotateKey({ messageMissingKey: "version is required" })),
|
|
38
|
+
registries: Schema.Record(Schema.String, RegistryAccountsSchema).pipe(Schema.annotateKey({ messageMissingKey: "registries is required" })),
|
|
39
|
+
}).annotate({
|
|
40
|
+
identifier: "CredentialFile",
|
|
41
|
+
title: "Credential File",
|
|
42
|
+
description: "Your saved credentials, organized by registry URL.",
|
|
43
|
+
});
|
|
44
|
+
// -----------------------------------------------------------------------------
|
|
45
|
+
// Token Source (tagged union)
|
|
46
|
+
// -----------------------------------------------------------------------------
|
|
47
|
+
export class EnvVarTokenSource extends Data.TaggedClass("EnvVar") {
|
|
48
|
+
}
|
|
49
|
+
export class FlagTokenSource extends Data.TaggedClass("Flag") {
|
|
50
|
+
}
|
|
51
|
+
export class FileTokenSource extends Data.TaggedClass("File") {
|
|
52
|
+
}
|
|
53
|
+
export class CredentialStoreTokenSource extends Data.TaggedClass("CredentialStore") {
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic in-memory Layer implementations of the registry-auth
|
|
3
|
+
* services. Tests and specifications may import this module; production
|
|
4
|
+
* source composes real services from `./live` at the application boundary.
|
|
5
|
+
*
|
|
6
|
+
* @experimental This API is unstable and may change without notice.
|
|
7
|
+
*/
|
|
8
|
+
export { AuthClientTest } from "./auth-client.js";
|
|
9
|
+
export { CredentialStoreTest } from "./credential-store.js";
|
|
10
|
+
export { DeviceLoginInteractionTest, type DeviceLoginInteractionTestState, } from "./device-login.js";
|
|
11
|
+
export { AuthLoginInteractionTest, type AuthLoginInteractionTestState, } from "./login-interaction.js";
|
|
12
|
+
export { AuthLoginPresenterTest, type AuthLoginPresenterTestState } from "./login-presenter.js";
|
|
13
|
+
export { PendingDeviceLoginStoreTest } from "./pending-device-login-store.js";
|
|
14
|
+
//# sourceMappingURL=testing.d.ts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic in-memory Layer implementations of the registry-auth
|
|
3
|
+
* services. Tests and specifications may import this module; production
|
|
4
|
+
* source composes real services from `./live` at the application boundary.
|
|
5
|
+
*
|
|
6
|
+
* @experimental This API is unstable and may change without notice.
|
|
7
|
+
*/
|
|
8
|
+
export { AuthClientTest } from "./auth-client.js";
|
|
9
|
+
export { CredentialStoreTest } from "./credential-store.js";
|
|
10
|
+
export { DeviceLoginInteractionTest, } from "./device-login.js";
|
|
11
|
+
export { AuthLoginInteractionTest, } from "./login-interaction.js";
|
|
12
|
+
export { AuthLoginPresenterTest } from "./login-presenter.js";
|
|
13
|
+
export { PendingDeviceLoginStoreTest } from "./pending-device-login-store.js";
|
|
14
|
+
//# sourceMappingURL=testing.js.map
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token resolution with precedence chain.
|
|
3
|
+
*
|
|
4
|
+
* Resolves authentication tokens from multiple sources in priority order:
|
|
5
|
+
* 1. AXM_TOKEN environment variable
|
|
6
|
+
* 2. AXM_TOKEN_FILE
|
|
7
|
+
* 3. --token flag (per-command, passed as parameter)
|
|
8
|
+
* 4. Credential store lookup by registry URL
|
|
9
|
+
*
|
|
10
|
+
* @experimental This API is unstable and may change without notice.
|
|
11
|
+
*/
|
|
12
|
+
import * as Effect from "effect/Effect";
|
|
13
|
+
import * as Option from "effect/Option";
|
|
14
|
+
import { type Handle } from "@agentxm/extension-model/unstable/extensions/handle";
|
|
15
|
+
import { RegistryAuthFailed, type AuthError, type AuthLoginRequired, type AuthTokenPolicyRequired } from "./errors.js";
|
|
16
|
+
import { AuthClient } from "./auth-client.js";
|
|
17
|
+
import { CredentialStore } from "./credential-store.js";
|
|
18
|
+
import { CredentialStoreTokenSource, type TokenSource } from "./schema.js";
|
|
19
|
+
/**
|
|
20
|
+
* Read the locally-stored user handle for the given registry URL.
|
|
21
|
+
*
|
|
22
|
+
* Offline only — does not call the registry. Returns Option.none() when
|
|
23
|
+
* persisted credentials are unsupported, no credentials are stored, or the
|
|
24
|
+
* stored entry has no handle.
|
|
25
|
+
*/
|
|
26
|
+
export declare const getCurrentUserHandle: (registryUrl: string) => Effect.Effect<Option.Option<Handle>, RegistryAuthFailed, CredentialStore>;
|
|
27
|
+
/**
|
|
28
|
+
* Resolve a token from the credential store only.
|
|
29
|
+
*
|
|
30
|
+
* Looks up stored credentials by origin URL. Does not check env vars or flags.
|
|
31
|
+
*/
|
|
32
|
+
export declare const resolveStoredToken: (origin: string) => Effect.Effect<Option.Option<CredentialStoreTokenSource>, RegistryAuthFailed, CredentialStore>;
|
|
33
|
+
export declare const refreshStoredToken: (tokenSource: CredentialStoreTokenSource) => Effect.Effect<CredentialStoreTokenSource, AuthError, AuthClient | CredentialStore>;
|
|
34
|
+
/**
|
|
35
|
+
* Resolve a token from ambient sources only (env var, file, and flag).
|
|
36
|
+
*
|
|
37
|
+
* Does not access the credential store.
|
|
38
|
+
*
|
|
39
|
+
* Precedence:
|
|
40
|
+
* 1. AXM_TOKEN env var
|
|
41
|
+
* 2. AXM_TOKEN_FILE
|
|
42
|
+
* 3. --token flag (passed as `flagToken` parameter)
|
|
43
|
+
*/
|
|
44
|
+
export declare const resolveAmbientToken: (flagToken?: string) => Effect.Effect<Option.Option<TokenSource>, RegistryAuthFailed, never>;
|
|
45
|
+
/**
|
|
46
|
+
* Resolve the token that should be attached to a specific request target.
|
|
47
|
+
*
|
|
48
|
+
* Ambient sources are only considered for the configured default registry.
|
|
49
|
+
* Stored credentials remain scoped by request origin.
|
|
50
|
+
*/
|
|
51
|
+
export declare const resolveRequestToken: (requestUrl: string, defaultRegistryUrl: string, flagToken?: string) => Effect.Effect<Option.Option<TokenSource>, RegistryAuthFailed, CredentialStore>;
|
|
52
|
+
/**
|
|
53
|
+
* Resolve a token from the precedence chain.
|
|
54
|
+
*
|
|
55
|
+
* Precedence:
|
|
56
|
+
* 1. AXM_TOKEN env var
|
|
57
|
+
* 2. AXM_TOKEN_FILE
|
|
58
|
+
* 3. --token flag (passed as `flagToken` parameter)
|
|
59
|
+
* 4. CredentialStore lookup by registry URL
|
|
60
|
+
*
|
|
61
|
+
* Returns the stored token as-is without proactive refresh. Callers should
|
|
62
|
+
* handle 401 responses from the server (e.g., prompt re-login). The auth
|
|
63
|
+
* middleware handles automatic refresh on 401 for requests going through
|
|
64
|
+
* HttpClient.
|
|
65
|
+
*
|
|
66
|
+
* Returns `Option.none()` when no token is available from any source.
|
|
67
|
+
*/
|
|
68
|
+
export declare const resolveToken: (registryUrl: string, flagToken?: string) => Effect.Effect<Option.Option<TokenSource>, RegistryAuthFailed, CredentialStore>;
|
|
69
|
+
/**
|
|
70
|
+
* Resolve a token and fail with the correct auth policy error when none is available.
|
|
71
|
+
*
|
|
72
|
+
* In CI environments, persisted credentials are disabled by policy, so
|
|
73
|
+
* callers should surface the auth policy error instead of suggesting `axm login`.
|
|
74
|
+
*/
|
|
75
|
+
export declare const resolveRequiredToken: (registryUrl: string, options?: {
|
|
76
|
+
readonly flagToken?: string;
|
|
77
|
+
readonly missingTokenError?: AuthError;
|
|
78
|
+
}) => Effect.Effect<TokenSource, RegistryAuthFailed | AuthLoginRequired | AuthTokenPolicyRequired | AuthError, CredentialStore>;
|
|
79
|
+
//# sourceMappingURL=token-resolution.d.ts.map
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token resolution with precedence chain.
|
|
3
|
+
*
|
|
4
|
+
* Resolves authentication tokens from multiple sources in priority order:
|
|
5
|
+
* 1. AXM_TOKEN environment variable
|
|
6
|
+
* 2. AXM_TOKEN_FILE
|
|
7
|
+
* 3. --token flag (per-command, passed as parameter)
|
|
8
|
+
* 4. Credential store lookup by registry URL
|
|
9
|
+
*
|
|
10
|
+
* @experimental This API is unstable and may change without notice.
|
|
11
|
+
*/
|
|
12
|
+
import * as Effect from "effect/Effect";
|
|
13
|
+
import * as FileSystem from "effect/FileSystem";
|
|
14
|
+
import * as Option from "effect/Option";
|
|
15
|
+
import { envOption } from "./internal/environment.js";
|
|
16
|
+
import { normalizeHandle } from "@agentxm/extension-model/unstable/extensions/handle";
|
|
17
|
+
import { authLoginRequired, RegistryAuthFailed, } from "./errors.js";
|
|
18
|
+
import { AuthClient } from "./auth-client.js";
|
|
19
|
+
import { CredentialStore, makePersistedCredentialsUnsupportedError } from "./credential-store.js";
|
|
20
|
+
import { CredentialStoreTokenSource, EnvVarTokenSource, FileTokenSource, FlagTokenSource, } from "./schema.js";
|
|
21
|
+
// -----------------------------------------------------------------------------
|
|
22
|
+
// Token resolution
|
|
23
|
+
// -----------------------------------------------------------------------------
|
|
24
|
+
const parseOrigin = (url) => Effect.try({
|
|
25
|
+
try: () => new URL(url).origin,
|
|
26
|
+
catch: (error) => new RegistryAuthFailed({
|
|
27
|
+
category: "validation",
|
|
28
|
+
detail: `Invalid URL: ${url}`,
|
|
29
|
+
suggestions: [{ description: "Check the registry URL in your settings." }],
|
|
30
|
+
cause: error,
|
|
31
|
+
}),
|
|
32
|
+
});
|
|
33
|
+
const makeStoredTokenSource = (registryUrl, credentials) => new CredentialStoreTokenSource({
|
|
34
|
+
token: credentials.access_token,
|
|
35
|
+
refresh_token: credentials.refresh_token,
|
|
36
|
+
expires_at: credentials.expires_at,
|
|
37
|
+
registryUrl,
|
|
38
|
+
});
|
|
39
|
+
const persistRefreshedCredentials = (registryUrl, token) => Effect.gen(function* () {
|
|
40
|
+
const store = yield* CredentialStore;
|
|
41
|
+
const existing = yield* store.load(registryUrl);
|
|
42
|
+
const handle = Option.match(existing, {
|
|
43
|
+
onNone: () => normalizeHandle("@unknown"),
|
|
44
|
+
onSome: (credentials) => credentials.handle,
|
|
45
|
+
});
|
|
46
|
+
yield* store.save(registryUrl, handle, {
|
|
47
|
+
access_token: token.access_token,
|
|
48
|
+
refresh_token: token.refresh_token,
|
|
49
|
+
expires_at: token.expires_at,
|
|
50
|
+
});
|
|
51
|
+
return makeStoredTokenSource(registryUrl, token);
|
|
52
|
+
});
|
|
53
|
+
const makeLoginRequiredError = () => authLoginRequired();
|
|
54
|
+
/**
|
|
55
|
+
* Read the locally-stored user handle for the given registry URL.
|
|
56
|
+
*
|
|
57
|
+
* Offline only — does not call the registry. Returns Option.none() when
|
|
58
|
+
* persisted credentials are unsupported, no credentials are stored, or the
|
|
59
|
+
* stored entry has no handle.
|
|
60
|
+
*/
|
|
61
|
+
export const getCurrentUserHandle = (registryUrl) => Effect.gen(function* () {
|
|
62
|
+
const store = yield* CredentialStore;
|
|
63
|
+
if (!store.allowsPersistedCredentials) {
|
|
64
|
+
return Option.none();
|
|
65
|
+
}
|
|
66
|
+
const stored = yield* store.load(registryUrl);
|
|
67
|
+
return Option.map(stored, (credentials) => credentials.handle);
|
|
68
|
+
});
|
|
69
|
+
/**
|
|
70
|
+
* Resolve a token from the credential store only.
|
|
71
|
+
*
|
|
72
|
+
* Looks up stored credentials by origin URL. Does not check env vars or flags.
|
|
73
|
+
*/
|
|
74
|
+
export const resolveStoredToken = (origin) => Effect.gen(function* () {
|
|
75
|
+
const store = yield* CredentialStore;
|
|
76
|
+
if (!store.allowsPersistedCredentials) {
|
|
77
|
+
return Option.none();
|
|
78
|
+
}
|
|
79
|
+
const stored = yield* store.load(origin);
|
|
80
|
+
return Option.map(stored, (credentials) => makeStoredTokenSource(origin, credentials));
|
|
81
|
+
});
|
|
82
|
+
export const refreshStoredToken = (tokenSource) => Effect.gen(function* () {
|
|
83
|
+
const authClient = yield* AuthClient;
|
|
84
|
+
const token = yield* authClient.refreshToken(tokenSource.refresh_token);
|
|
85
|
+
return yield* persistRefreshedCredentials(tokenSource.registryUrl, token);
|
|
86
|
+
});
|
|
87
|
+
/**
|
|
88
|
+
* Resolve a token from ambient sources only (env var, file, and flag).
|
|
89
|
+
*
|
|
90
|
+
* Does not access the credential store.
|
|
91
|
+
*
|
|
92
|
+
* Precedence:
|
|
93
|
+
* 1. AXM_TOKEN env var
|
|
94
|
+
* 2. AXM_TOKEN_FILE
|
|
95
|
+
* 3. --token flag (passed as `flagToken` parameter)
|
|
96
|
+
*/
|
|
97
|
+
export const resolveAmbientToken = (flagToken) => Effect.gen(function* () {
|
|
98
|
+
const envTokenOpt = yield* envOption("AXM_TOKEN");
|
|
99
|
+
const envToken = Option.getOrUndefined(envTokenOpt);
|
|
100
|
+
if (envToken !== undefined && envToken.length > 0) {
|
|
101
|
+
return Option.some(new EnvVarTokenSource({ token: envToken }));
|
|
102
|
+
}
|
|
103
|
+
const tokenFileOpt = yield* envOption("AXM_TOKEN_FILE");
|
|
104
|
+
if (Option.isSome(tokenFileOpt) && tokenFileOpt.value.length > 0) {
|
|
105
|
+
const maybeFs = yield* Effect.serviceOption(FileSystem.FileSystem);
|
|
106
|
+
if (Option.isNone(maybeFs)) {
|
|
107
|
+
return yield* new RegistryAuthFailed({
|
|
108
|
+
category: "internal",
|
|
109
|
+
detail: "AXM_TOKEN_FILE cannot be read in this runtime.",
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
const fs = maybeFs.value;
|
|
113
|
+
const token = yield* fs.readFileString(tokenFileOpt.value).pipe(Effect.map((content) => content.trim()), Effect.mapError((error) => new RegistryAuthFailed({
|
|
114
|
+
category: "auth",
|
|
115
|
+
detail: `Could not read AXM_TOKEN_FILE at ${tokenFileOpt.value}.`,
|
|
116
|
+
suggestions: [
|
|
117
|
+
{ description: "Check that AXM_TOKEN_FILE names a readable token file." },
|
|
118
|
+
],
|
|
119
|
+
cause: error,
|
|
120
|
+
})));
|
|
121
|
+
if (token.length === 0) {
|
|
122
|
+
return yield* new RegistryAuthFailed({
|
|
123
|
+
category: "validation",
|
|
124
|
+
detail: `AXM_TOKEN_FILE at ${tokenFileOpt.value} is empty.`,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
return Option.some(new FileTokenSource({ token, path: tokenFileOpt.value }));
|
|
128
|
+
}
|
|
129
|
+
if (flagToken !== undefined && flagToken.length > 0) {
|
|
130
|
+
return Option.some(new FlagTokenSource({ token: flagToken }));
|
|
131
|
+
}
|
|
132
|
+
return Option.none();
|
|
133
|
+
});
|
|
134
|
+
/**
|
|
135
|
+
* Resolve the token that should be attached to a specific request target.
|
|
136
|
+
*
|
|
137
|
+
* Ambient sources are only considered for the configured default registry.
|
|
138
|
+
* Stored credentials remain scoped by request origin.
|
|
139
|
+
*/
|
|
140
|
+
export const resolveRequestToken = (requestUrl, defaultRegistryUrl, flagToken) => Effect.gen(function* () {
|
|
141
|
+
const requestOrigin = yield* parseOrigin(requestUrl);
|
|
142
|
+
const defaultRegistryOrigin = yield* parseOrigin(defaultRegistryUrl);
|
|
143
|
+
if (requestOrigin === defaultRegistryOrigin) {
|
|
144
|
+
const ambient = yield* resolveAmbientToken(flagToken);
|
|
145
|
+
if (Option.isSome(ambient)) {
|
|
146
|
+
return ambient;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return yield* resolveStoredToken(requestOrigin);
|
|
150
|
+
});
|
|
151
|
+
/**
|
|
152
|
+
* Resolve a token from the precedence chain.
|
|
153
|
+
*
|
|
154
|
+
* Precedence:
|
|
155
|
+
* 1. AXM_TOKEN env var
|
|
156
|
+
* 2. AXM_TOKEN_FILE
|
|
157
|
+
* 3. --token flag (passed as `flagToken` parameter)
|
|
158
|
+
* 4. CredentialStore lookup by registry URL
|
|
159
|
+
*
|
|
160
|
+
* Returns the stored token as-is without proactive refresh. Callers should
|
|
161
|
+
* handle 401 responses from the server (e.g., prompt re-login). The auth
|
|
162
|
+
* middleware handles automatic refresh on 401 for requests going through
|
|
163
|
+
* HttpClient.
|
|
164
|
+
*
|
|
165
|
+
* Returns `Option.none()` when no token is available from any source.
|
|
166
|
+
*/
|
|
167
|
+
export const resolveToken = (registryUrl, flagToken) => Effect.gen(function* () {
|
|
168
|
+
const ambient = yield* resolveAmbientToken(flagToken);
|
|
169
|
+
if (Option.isSome(ambient))
|
|
170
|
+
return ambient;
|
|
171
|
+
return yield* resolveStoredToken(registryUrl);
|
|
172
|
+
});
|
|
173
|
+
/**
|
|
174
|
+
* Resolve a token and fail with the correct auth policy error when none is available.
|
|
175
|
+
*
|
|
176
|
+
* In CI environments, persisted credentials are disabled by policy, so
|
|
177
|
+
* callers should surface the auth policy error instead of suggesting `axm login`.
|
|
178
|
+
*/
|
|
179
|
+
export const resolveRequiredToken = (registryUrl, options) => Effect.gen(function* () {
|
|
180
|
+
const token = yield* resolveToken(registryUrl, options?.flagToken);
|
|
181
|
+
if (Option.isSome(token)) {
|
|
182
|
+
return token.value;
|
|
183
|
+
}
|
|
184
|
+
const store = yield* CredentialStore;
|
|
185
|
+
if (!store.allowsPersistedCredentials) {
|
|
186
|
+
return yield* makePersistedCredentialsUnsupportedError();
|
|
187
|
+
}
|
|
188
|
+
return yield* options?.missingTokenError ?? makeLoginRequiredError();
|
|
189
|
+
});
|
|
190
|
+
//# sourceMappingURL=token-resolution.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agentxm/registry-auth",
|
|
3
|
+
"version": "0.28.4-bootstrap.0",
|
|
4
|
+
"description": "AXM registry-auth feature: login, logout, token, identity inspection, device and loopback flows, and credential lifecycle for the axm CLI. Unstable and unsupported — use the axm.sh CLI.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "FSL-1.1-MIT",
|
|
7
|
+
"homepage": "https://axm.sh",
|
|
8
|
+
"bugs": {
|
|
9
|
+
"url": "https://github.com/agentxm/axm/issues"
|
|
10
|
+
},
|
|
11
|
+
"author": "AgentXM <hello@agentxm.ai> (https://agentxm.ai)",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/agentxm/axm.git",
|
|
15
|
+
"directory": "packages/registry-auth"
|
|
16
|
+
},
|
|
17
|
+
"sideEffects": false,
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/src/index.d.ts",
|
|
21
|
+
"default": "./dist/src/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./live": {
|
|
24
|
+
"types": "./dist/src/live.d.ts",
|
|
25
|
+
"default": "./dist/src/live.js"
|
|
26
|
+
},
|
|
27
|
+
"./testing": {
|
|
28
|
+
"types": "./dist/src/testing.d.ts",
|
|
29
|
+
"default": "./dist/src/testing.js"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist/src/",
|
|
34
|
+
"!**/*.map"
|
|
35
|
+
],
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=22.19.0"
|
|
41
|
+
},
|
|
42
|
+
"nx": {
|
|
43
|
+
"includedScripts": []
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@napi-rs/keyring": "^1.3.0",
|
|
47
|
+
"effect": "4.0.0-rc.112",
|
|
48
|
+
"proper-lockfile": "^4.1.2",
|
|
49
|
+
"@agentxm/registry-protocol": "^0.28.4-bootstrap.0",
|
|
50
|
+
"@agentxm/registry-client": "^0.28.4-bootstrap.0",
|
|
51
|
+
"@agentxm/extension-model": "^0.28.4-bootstrap.0"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@effect/platform-node": "4.0.0-rc.112",
|
|
55
|
+
"@effect/vitest": "4.0.0-rc.112",
|
|
56
|
+
"@types/bun": "^1.3.14",
|
|
57
|
+
"@types/proper-lockfile": "^4.1.4",
|
|
58
|
+
"@typescript/native": "npm:typescript@^7.0.2",
|
|
59
|
+
"typescript": "npm:@typescript/typescript6@^6.0.2",
|
|
60
|
+
"vitest": "^4.1.10"
|
|
61
|
+
}
|
|
62
|
+
}
|