mirror of
https://github.com/Sea-Haven-Industries/sh-mcp.git
synced 2026-09-30 07:43:17 +00:00
62 lines
2.1 KiB
TypeScript
62 lines
2.1 KiB
TypeScript
|
|
/**
|
||
|
|
* The Google Group → Cognito group mapping this sync reconciles, and the pure
|
||
|
|
* membership-diff logic. Google Groups are the single source of truth for
|
||
|
|
* entitlement (design.md §2.3); this Lambda mirrors their membership into the
|
||
|
|
* matching Cognito groups every 5 minutes so the pre-token Lambda can map
|
||
|
|
* Cognito group → suppressed scopes without a hot-path Directory call.
|
||
|
|
*/
|
||
|
|
|
||
|
|
/** Workspace domain the managed groups live under. Overridable via env at deploy. */
|
||
|
|
export const DEFAULT_DOMAIN = 'seahavenind.com';
|
||
|
|
|
||
|
|
/** The four managed groups (Cognito group name === Google Group local-part). */
|
||
|
|
export const MANAGED_GROUP_NAMES = [
|
||
|
|
'sh-mcp-ops',
|
||
|
|
'sh-mcp-assistant',
|
||
|
|
'sh-mcp-finance',
|
||
|
|
'sh-mcp-admin',
|
||
|
|
] as const;
|
||
|
|
|
||
|
|
export type ManagedGroupName = (typeof MANAGED_GROUP_NAMES)[number];
|
||
|
|
|
||
|
|
export interface ManagedGroup {
|
||
|
|
/** Cognito group name. */
|
||
|
|
cognito: ManagedGroupName;
|
||
|
|
/** Fully-qualified Google Group address. */
|
||
|
|
googleEmail: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Build the managed-group list for a workspace domain. */
|
||
|
|
export function managedGroups(domain: string = DEFAULT_DOMAIN): ManagedGroup[] {
|
||
|
|
return MANAGED_GROUP_NAMES.map((cognito) => ({ cognito, googleEmail: `${cognito}@${domain}` }));
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Normalize an email for set comparison (Google/Cognito casing is not stable). */
|
||
|
|
export function normalizeEmail(email: string): string {
|
||
|
|
return email.trim().toLowerCase();
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface MembershipDiff {
|
||
|
|
toAdd: string[];
|
||
|
|
toRemove: string[];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Compute the membership changes to make a Cognito group match the Google group.
|
||
|
|
* Comparison is case-insensitive; returned values are normalized (lowercased).
|
||
|
|
*
|
||
|
|
* @param current members currently in the Cognito group.
|
||
|
|
* @param desired members the Google group says should be present.
|
||
|
|
*/
|
||
|
|
export function computeMembershipDiff(
|
||
|
|
current: readonly string[],
|
||
|
|
desired: readonly string[],
|
||
|
|
): MembershipDiff {
|
||
|
|
const cur = new Set(current.map(normalizeEmail));
|
||
|
|
const des = new Set(desired.map(normalizeEmail));
|
||
|
|
return {
|
||
|
|
toAdd: [...des].filter((e) => !cur.has(e)),
|
||
|
|
toRemove: [...cur].filter((e) => !des.has(e)),
|
||
|
|
};
|
||
|
|
}
|