mirror of https://github.com/openclaw/openclaw.git
124 lines
3.2 KiB
TypeScript
124 lines
3.2 KiB
TypeScript
import { isNonEmptyString, isRecord } from "./shared.js";
|
|
import { listAuthProfileSecretTargetEntries } from "./target-registry.js";
|
|
|
|
export type AuthProfileCredentialType = "api_key" | "token";
|
|
|
|
type AuthProfileFieldSpec = {
|
|
valueField: string;
|
|
refField: string;
|
|
};
|
|
|
|
type ApiKeyCredentialVisit = {
|
|
kind: "api_key";
|
|
profileId: string;
|
|
provider: string;
|
|
profile: Record<string, unknown>;
|
|
valueField: string;
|
|
refField: string;
|
|
value: unknown;
|
|
refValue: unknown;
|
|
};
|
|
|
|
type TokenCredentialVisit = {
|
|
kind: "token";
|
|
profileId: string;
|
|
provider: string;
|
|
profile: Record<string, unknown>;
|
|
valueField: string;
|
|
refField: string;
|
|
value: unknown;
|
|
refValue: unknown;
|
|
};
|
|
|
|
type OauthCredentialVisit = {
|
|
kind: "oauth";
|
|
profileId: string;
|
|
provider: string;
|
|
profile: Record<string, unknown>;
|
|
hasAccess: boolean;
|
|
hasRefresh: boolean;
|
|
};
|
|
|
|
export type AuthProfileCredentialVisit =
|
|
| ApiKeyCredentialVisit
|
|
| TokenCredentialVisit
|
|
| OauthCredentialVisit;
|
|
|
|
function getAuthProfileFieldName(pathPattern: string): string {
|
|
const segments = pathPattern.split(".").filter(Boolean);
|
|
return segments[segments.length - 1] ?? "";
|
|
}
|
|
|
|
const AUTH_PROFILE_FIELD_SPEC_BY_TYPE = (() => {
|
|
const defaults: Record<AuthProfileCredentialType, AuthProfileFieldSpec> = {
|
|
api_key: { valueField: "key", refField: "keyRef" },
|
|
token: { valueField: "token", refField: "tokenRef" },
|
|
};
|
|
for (const target of listAuthProfileSecretTargetEntries()) {
|
|
if (!target.authProfileType) {
|
|
continue;
|
|
}
|
|
defaults[target.authProfileType] = {
|
|
valueField: getAuthProfileFieldName(target.pathPattern),
|
|
refField:
|
|
target.refPathPattern !== undefined
|
|
? getAuthProfileFieldName(target.refPathPattern)
|
|
: defaults[target.authProfileType].refField,
|
|
};
|
|
}
|
|
return defaults;
|
|
})();
|
|
|
|
export function getAuthProfileFieldSpec(type: AuthProfileCredentialType): AuthProfileFieldSpec {
|
|
return AUTH_PROFILE_FIELD_SPEC_BY_TYPE[type];
|
|
}
|
|
|
|
export function* iterateAuthProfileCredentials(
|
|
profiles: Record<string, unknown>,
|
|
): Iterable<AuthProfileCredentialVisit> {
|
|
for (const [profileId, value] of Object.entries(profiles)) {
|
|
if (!isRecord(value) || !isNonEmptyString(value.provider)) {
|
|
continue;
|
|
}
|
|
const provider = String(value.provider);
|
|
if (value.type === "api_key") {
|
|
const spec = getAuthProfileFieldSpec("api_key");
|
|
yield {
|
|
kind: "api_key",
|
|
profileId,
|
|
provider,
|
|
profile: value,
|
|
valueField: spec.valueField,
|
|
refField: spec.refField,
|
|
value: value[spec.valueField],
|
|
refValue: value[spec.refField],
|
|
};
|
|
continue;
|
|
}
|
|
if (value.type === "token") {
|
|
const spec = getAuthProfileFieldSpec("token");
|
|
yield {
|
|
kind: "token",
|
|
profileId,
|
|
provider,
|
|
profile: value,
|
|
valueField: spec.valueField,
|
|
refField: spec.refField,
|
|
value: value[spec.valueField],
|
|
refValue: value[spec.refField],
|
|
};
|
|
continue;
|
|
}
|
|
if (value.type === "oauth") {
|
|
yield {
|
|
kind: "oauth",
|
|
profileId,
|
|
provider,
|
|
profile: value,
|
|
hasAccess: isNonEmptyString(value.access),
|
|
hasRefresh: isNonEmptyString(value.refresh),
|
|
};
|
|
}
|
|
}
|
|
}
|