@vegait/accounts-sdk 0.1.0-beta.0 → 0.1.1-beta.45391
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/dist/index.cjs +1 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/claims.ts","../src/persona.ts","../src/productCatalog.ts","../src/identityModel.ts"],"sourcesContent":["// Barrel do @vegait/accounts-sdk. Preenchido pelas tasks seguintes.\n\nexport type { AccountsClaims } from \"./claims\";\nexport {\n decodeJwtPayload,\n decodeAccessToken,\n parseJsonArrayClaim,\n normalizeClaimArray,\n} from \"./claims\";\n\nexport type { Persona } from \"./persona\";\nexport { derivePersona } from \"./persona\";\n\nexport type { ProductMeta, CatalogProduct } from \"./productCatalog\";\nexport {\n PRODUCT_CATALOG,\n resolveProduct,\n getAccessibleProducts,\n getCatalogWithAccess,\n} from \"./productCatalog\";\n\nexport type { IdentityModel } from \"./identityModel\";\nexport { buildIdentityModel } from \"./identityModel\";\n","// Decoder de payload JWT sem verificacao criptografica. Universal (browser +\n// Node). Usar APENAS para extrair claims de tokens ja confiaveis (recebidos do\n// Accounts via fluxo OIDC). NUNCA para validar tokens de origem externa.\n\nexport function decodeJwtPayload<T = Record<string, unknown>>(token: string): T {\n const parts = token.split(\".\");\n if (parts.length !== 3) {\n throw new Error(\"Invalid JWT format\");\n }\n const payload = parts[1].replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padded = payload + \"=\".repeat((4 - (payload.length % 4)) % 4);\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n const json = new TextDecoder(\"utf-8\").decode(bytes);\n return JSON.parse(json) as T;\n}\n\n// Claims do AT emitido pelo Accounts via OpenIddict. Tudo opcional (nem todo\n// campo chega em todo contexto). unit_ids/products vem como string contendo\n// JSON array. platform_role aparece so para Time VEGA. Espelha o token; fonte\n// da verdade = VegaClaimsHandler no accounts.api.\nexport type AccountsClaims = {\n sub?: string;\n email?: string;\n name?: string;\n platform_role?: string;\n can_manage_scope_members?: string;\n org_id?: string | string[];\n unit_ids?: string;\n active_unit_id?: string;\n products?: string;\n exp?: number;\n iat?: number;\n iss?: string;\n aud?: string | string[];\n};\n\n// Normaliza claim que pode vir como string ou array (OpenIddict emite array\n// quando ha multiplos valores, scalar quando ha um so).\nexport function normalizeClaimArray(\n value: string | string[] | undefined,\n): string[] {\n if (!value) return [];\n return Array.isArray(value) ? value : [value];\n}\n\n// Parseia claim cujo value e string contendo JSON array (unit_ids, products).\n// Lista vazia em claim ausente ou JSON malformado.\nexport function parseJsonArrayClaim(value: string | undefined): string[] {\n if (!value) return [];\n try {\n const parsed = JSON.parse(value);\n return Array.isArray(parsed)\n ? parsed.filter((v): v is string => typeof v === \"string\")\n : [];\n } catch {\n return [];\n }\n}\n\n// Wrapper safe que devolve null em vez de jogar em token invalido.\nexport function decodeAccessToken(\n token: string | null | undefined,\n): AccountsClaims | null {\n if (!token) return null;\n try {\n return decodeJwtPayload<AccountsClaims>(token);\n } catch {\n return null;\n }\n}\n","import type { AccountsClaims } from \"./claims\";\n\nexport type Persona = \"usuario\" | \"gestor\" | \"vega\";\n\n// Deriva a persona a partir das claims do AT. Fail-closed: sem claims ou sem\n// sinal de gestao, cai em 'usuario' (menor privilegio). platform_role (Time\n// VEGA) tem precedencia sobre a flag de gestor de cliente.\n// ATENCAO: presentation gating, NAO autorizacao (ver README).\nexport function derivePersona(claims: AccountsClaims | null): Persona {\n if (claims?.platform_role) return \"vega\";\n if (claims?.can_manage_scope_members === \"true\") return \"gestor\";\n return \"usuario\";\n}\n","import type { AccountsClaims } from \"./claims\";\nimport { parseJsonArrayClaim } from \"./claims\";\nimport { derivePersona } from \"./persona\";\n\n// Catalogo cliente-side dos produtos VEGA. Mapeia o code (claim `products` do\n// AT) pra display name + URL default + accent. codes batem com o seed do\n// backend (SeedMediaHubInProductCatalog etc.). ssoEnabled = produto JA loga via\n// Accounts (OIDC unificado); a gaveta so mostra ssoEnabled=true.\n//\n// URLs aqui sao DEFAULTS de producao. O consumidor sobrescreve por ambiente via\n// o parametro `urls` (do seu proprio env) -- o SDK NAO le process.env.\n\nexport type ProductMeta = {\n code: string;\n name: string;\n description: string;\n url: string;\n accent: string;\n ssoEnabled: boolean;\n};\n\nexport const PRODUCT_CATALOG: Record<string, ProductMeta> = {\n accounts: {\n code: \"accounts\",\n name: \"Accounts\",\n description: \"Identidade unificada do ecossistema\",\n url: \"/\",\n accent: \"#1F2E52\",\n ssoEnabled: true, // e o proprio IdP; excluido da gaveta de qualquer forma\n },\n \"media-hub\": {\n code: \"media-hub\",\n name: \"Media Hub\",\n description: \"Sinalizacao digital nas unidades\",\n url: \"https://media-hub.vega.com.br/\",\n accent: \"#EF802D\",\n ssoEnabled: true,\n },\n sig: {\n code: \"sig\",\n name: \"SIG\",\n description: \"Housekeeping e governanca das unidades\",\n url: \"https://sig.app.vegait.com/\",\n accent: \"#B0C925\",\n ssoEnabled: true,\n },\n gdi: {\n code: \"gdi\",\n name: \"GDI\",\n description: \"Gestao de dispositivos e internet\",\n url: \"https://gdi.vega.com.br/\",\n accent: \"#7B8B7E\",\n ssoEnabled: false,\n },\n sim: {\n code: \"sim\",\n name: \"SIM\",\n description: \"Service Issue Management\",\n url: \"https://sim.vega.com.br/\",\n accent: \"#5B7DB1\",\n ssoEnabled: false,\n },\n hxp: {\n code: \"hxp\",\n name: \"HXP\",\n description: \"Hotel Experience Platform\",\n url: \"https://hxp.vega.com.br/\",\n accent: \"#9B6A4F\",\n ssoEnabled: false,\n },\n feedback: {\n code: \"feedback\",\n name: \"Feedback\",\n description: \"Pesquisas e NPS de hospedes\",\n url: \"https://feedback.vega.com.br/\",\n accent: \"#C26A8C\",\n ssoEnabled: false,\n },\n behavior: {\n code: \"behavior\",\n name: \"Behavior\",\n description: \"Inteligencia comportamental\",\n url: \"https://behavior.vega.com.br/\",\n accent: \"#4A7C7E\",\n ssoEnabled: false,\n },\n};\n\n// Aliases de code legado -> canonico. Resolve dados gravados ANTES de uma\n// renomeacao (ex.: governanca -> sig) sem duplicar entrada no catalogo.\nconst LEGACY_CODE_ALIASES: Record<string, string> = {\n governanca: \"sig\",\n};\n\n// Resolve um code (aplicando alias) pra ProductMeta. `urls` sobrescreve a URL\n// default pelo code CANONICO. Code desconhecido => fallback ssoEnabled=false.\nexport function resolveProduct(\n code: string,\n urls?: Record<string, string>,\n): ProductMeta {\n const canonical = LEGACY_CODE_ALIASES[code] ?? code;\n const base =\n PRODUCT_CATALOG[canonical] ??\n ({\n code,\n name: code,\n description: \"\",\n url: \"#\",\n accent: \"#1F2E52\",\n ssoEnabled: false,\n } satisfies ProductMeta);\n const override = urls?.[canonical];\n return override ? { ...base, url: override } : base;\n}\n\nexport type CatalogProduct = ProductMeta & { accessible: boolean };\n\n// Catalogo COMPLETO pro app launcher (menos o Accounts, que e o proprio IdP),\n// com flag de acesso: Time VEGA acessa tudo; cliente acessa os codes da claim\n// `products` (aliases legados resolvidos). ssoEnabled NAO esconde produto aqui\n// — e metadado de COMO o produto abre, nao de quem ve. Sem claims: tudo\n// inacessivel (fail-closed). `urls` sobrescreve URLs por ambiente.\nexport function getCatalogWithAccess(\n claims: AccountsClaims | null,\n opts?: { urls?: Record<string, string> },\n): CatalogProduct[] {\n const urls = opts?.urls;\n const isVega = claims != null && derivePersona(claims) === \"vega\";\n const accessibleCodes = new Set(\n parseJsonArrayClaim(claims?.products).map(\n (code) => LEGACY_CODE_ALIASES[code] ?? code,\n ),\n );\n return Object.values(PRODUCT_CATALOG)\n .filter((p) => p.code !== \"accounts\")\n .map((p) => ({\n ...(urls?.[p.code] ? { ...p, url: urls[p.code] } : p),\n accessible: isVega || accessibleCodes.has(p.code),\n }));\n}\n\n// Produtos do app launcher. Time VEGA ve o catalogo inteiro (menos o Accounts,\n// que e o IdP); cliente ve so os codes da claim `products`. Ambos filtram\n// ssoEnabled. `urls` sobrescreve URLs por ambiente.\nexport function getAccessibleProducts(\n claims: AccountsClaims | null,\n opts?: { urls?: Record<string, string> },\n): ProductMeta[] {\n if (!claims) return [];\n const urls = opts?.urls;\n if (derivePersona(claims) === \"vega\") {\n return Object.values(PRODUCT_CATALOG)\n .filter((p) => p.code !== \"accounts\" && p.ssoEnabled)\n .map((p) => (urls?.[p.code] ? { ...p, url: urls[p.code] } : p));\n }\n return parseJsonArrayClaim(claims.products)\n .map((code) => resolveProduct(code, urls))\n .filter((p) => p.ssoEnabled);\n}\n","import type { AccountsClaims } from \"./claims\";\nimport { derivePersona, type Persona } from \"./persona\";\nimport {\n getAccessibleProducts,\n getCatalogWithAccess,\n type CatalogProduct,\n type ProductMeta,\n} from \"./productCatalog\";\n\n// Modelo de dados da casca de identidade (SEM React). O host mapeia isto pros\n// props do <IdentityBar> do @vegait/lyra-ds-v2, adicionando icones/labels/\n// callbacks a partir de `capabilities`.\nexport type IdentityModel = {\n persona: Persona;\n user: { name: string; email: string };\n products: ProductMeta[];\n /** Catalogo completo (menos Accounts) com flag de acesso — pro waffle\n * mostrar tudo e desabilitar o que a persona nao acessa. `products`\n * permanece so-acessiveis por retrocompat (SIG consome hoje). */\n catalog: CatalogProduct[];\n currentProductCode?: string;\n capabilities: {\n manageUsers: boolean; // gestor/vega\n adminConsole: boolean; // vega\n switchContext: boolean; // gestor/vega\n manageNetwork: boolean; // gestor (rodape do launcher)\n };\n};\n\nexport function buildIdentityModel(\n claims: AccountsClaims | null,\n cfg?: { currentProductCode?: string; urls?: Record<string, string> },\n): IdentityModel {\n const persona = derivePersona(claims);\n return {\n persona,\n user: { name: claims?.name ?? \"\", email: claims?.email ?? \"\" },\n products: getAccessibleProducts(claims, { urls: cfg?.urls }),\n catalog: getCatalogWithAccess(claims, { urls: cfg?.urls }),\n currentProductCode: cfg?.currentProductCode,\n capabilities: {\n manageUsers: persona === \"gestor\" || persona === \"vega\",\n adminConsole: persona === \"vega\",\n switchContext: persona === \"gestor\" || persona === \"vega\",\n manageNetwork: persona === \"gestor\",\n },\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/claims.ts","../src/persona.ts","../src/productCatalog.ts","../src/identityModel.ts"],"sourcesContent":["// Decoder de payload JWT sem verificacao criptografica. Universal (browser +\n// Node). Usar APENAS para extrair claims de tokens ja confiaveis (recebidos do\n// Accounts via fluxo OIDC). NUNCA para validar tokens de origem externa.\n\nexport function decodeJwtPayload<T = Record<string, unknown>>(token: string): T {\n const parts = token.split(\".\");\n if (parts.length !== 3) {\n throw new Error(\"Invalid JWT format\");\n }\n const payload = parts[1].replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padded = payload + \"=\".repeat((4 - (payload.length % 4)) % 4);\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n const json = new TextDecoder(\"utf-8\").decode(bytes);\n return JSON.parse(json) as T;\n}\n\n// Claims do AT emitido pelo Accounts via OpenIddict. Tudo opcional (nem todo\n// campo chega em todo contexto). unit_ids/products vem como string contendo\n// JSON array. platform_role aparece so para Time VEGA. Espelha o token; fonte\n// da verdade = VegaClaimsHandler no accounts.api.\nexport type AccountsClaims = {\n sub?: string;\n email?: string;\n name?: string;\n platform_role?: string;\n can_manage_scope_members?: string;\n org_id?: string | string[];\n unit_ids?: string;\n active_unit_id?: string;\n products?: string;\n exp?: number;\n iat?: number;\n iss?: string;\n aud?: string | string[];\n};\n\n// Normaliza claim que pode vir como string ou array (OpenIddict emite array\n// quando ha multiplos valores, scalar quando ha um so).\nexport function normalizeClaimArray(\n value: string | string[] | undefined,\n): string[] {\n if (!value) return [];\n return Array.isArray(value) ? value : [value];\n}\n\n// Parseia claim cujo value e string contendo JSON array (unit_ids, products).\n// Lista vazia em claim ausente ou JSON malformado.\nexport function parseJsonArrayClaim(value: string | undefined): string[] {\n if (!value) return [];\n try {\n const parsed = JSON.parse(value);\n return Array.isArray(parsed)\n ? parsed.filter((v): v is string => typeof v === \"string\")\n : [];\n } catch {\n return [];\n }\n}\n\n// Wrapper safe que devolve null em vez de jogar em token invalido.\nexport function decodeAccessToken(\n token: string | null | undefined,\n): AccountsClaims | null {\n if (!token) return null;\n try {\n return decodeJwtPayload<AccountsClaims>(token);\n } catch {\n return null;\n }\n}\n","import type { AccountsClaims } from \"./claims\";\n\nexport type Persona = \"usuario\" | \"gestor\" | \"vega\";\n\n// Deriva a persona a partir das claims do AT. Fail-closed: sem claims ou sem\n// sinal de gestao, cai em 'usuario' (menor privilegio). platform_role (Time\n// VEGA) tem precedencia sobre a flag de gestor de cliente.\n// ATENCAO: presentation gating, NAO autorizacao (ver README).\nexport function derivePersona(claims: AccountsClaims | null): Persona {\n if (claims?.platform_role) return \"vega\";\n if (claims?.can_manage_scope_members === \"true\") return \"gestor\";\n return \"usuario\";\n}\n","import type { AccountsClaims } from \"./claims\";\nimport { parseJsonArrayClaim } from \"./claims\";\nimport { derivePersona } from \"./persona\";\n\n// Catalogo cliente-side dos produtos VEGA. Mapeia o code (claim `products` do\n// AT) pra display name + URL default + accent. codes batem com o seed do\n// backend (SeedMediaHubInProductCatalog etc.). ssoEnabled = produto JA loga via\n// Accounts (OIDC unificado); a gaveta so mostra ssoEnabled=true.\n//\n// URLs aqui sao DEFAULTS de producao. O consumidor sobrescreve por ambiente via\n// o parametro `urls` (do seu proprio env) -- o SDK NAO le process.env.\n\nexport type ProductMeta = {\n code: string;\n name: string;\n description: string;\n url: string;\n accent: string;\n ssoEnabled: boolean;\n};\n\nexport const PRODUCT_CATALOG: Record<string, ProductMeta> = {\n accounts: {\n code: \"accounts\",\n name: \"Accounts\",\n description: \"Identidade unificada do ecossistema\",\n url: \"/\",\n accent: \"#1F2E52\",\n ssoEnabled: true, // e o proprio IdP; excluido da gaveta de qualquer forma\n },\n \"media-hub\": {\n code: \"media-hub\",\n name: \"Media Hub\",\n description: \"Sinalizacao digital nas unidades\",\n url: \"https://media-hub.vega.com.br/\",\n accent: \"#EF802D\",\n ssoEnabled: true,\n },\n sig: {\n code: \"sig\",\n name: \"SIG\",\n description: \"Housekeeping e governanca das unidades\",\n url: \"https://sig.app.vegait.com/\",\n accent: \"#B0C925\",\n ssoEnabled: true,\n },\n gdi: {\n code: \"gdi\",\n name: \"GDI\",\n description: \"Gestao de dispositivos e internet\",\n url: \"https://gdi.vega.com.br/\",\n accent: \"#7B8B7E\",\n ssoEnabled: false,\n },\n sim: {\n code: \"sim\",\n name: \"SIM\",\n description: \"Service Issue Management\",\n url: \"https://sim.vega.com.br/\",\n accent: \"#5B7DB1\",\n ssoEnabled: false,\n },\n hxp: {\n code: \"hxp\",\n name: \"HXP\",\n description: \"Hotel Experience Platform\",\n url: \"https://hxp.vega.com.br/\",\n accent: \"#9B6A4F\",\n ssoEnabled: false,\n },\n feedback: {\n code: \"feedback\",\n name: \"Feedback\",\n description: \"Pesquisas e NPS de hospedes\",\n url: \"https://feedback.vega.com.br/\",\n accent: \"#C26A8C\",\n ssoEnabled: false,\n },\n behavior: {\n code: \"behavior\",\n name: \"Behavior\",\n description: \"Inteligencia comportamental\",\n url: \"https://behavior.vega.com.br/\",\n accent: \"#4A7C7E\",\n ssoEnabled: false,\n },\n};\n\n// Aliases de code legado -> canonico. Resolve dados gravados ANTES de uma\n// renomeacao (ex.: governanca -> sig) sem duplicar entrada no catalogo.\nconst LEGACY_CODE_ALIASES: Record<string, string> = {\n governanca: \"sig\",\n};\n\n// Resolve um code (aplicando alias) pra ProductMeta. `urls` sobrescreve a URL\n// default pelo code CANONICO. Code desconhecido => fallback ssoEnabled=false.\nexport function resolveProduct(\n code: string,\n urls?: Record<string, string>,\n): ProductMeta {\n const canonical = LEGACY_CODE_ALIASES[code] ?? code;\n const base =\n PRODUCT_CATALOG[canonical] ??\n ({\n code,\n name: code,\n description: \"\",\n url: \"#\",\n accent: \"#1F2E52\",\n ssoEnabled: false,\n } satisfies ProductMeta);\n const override = urls?.[canonical];\n return override ? { ...base, url: override } : base;\n}\n\nexport type CatalogProduct = ProductMeta & { accessible: boolean };\n\n// Catalogo COMPLETO pro app launcher (menos o Accounts, que e o proprio IdP),\n// com flag de acesso: Time VEGA acessa tudo; cliente acessa os codes da claim\n// `products` (aliases legados resolvidos). ssoEnabled NAO esconde produto aqui\n// — e metadado de COMO o produto abre, nao de quem ve. Sem claims: tudo\n// inacessivel (fail-closed). `urls` sobrescreve URLs por ambiente.\nexport function getCatalogWithAccess(\n claims: AccountsClaims | null,\n opts?: { urls?: Record<string, string> },\n): CatalogProduct[] {\n const urls = opts?.urls;\n const isVega = claims != null && derivePersona(claims) === \"vega\";\n const accessibleCodes = new Set(\n parseJsonArrayClaim(claims?.products).map(\n (code) => LEGACY_CODE_ALIASES[code] ?? code,\n ),\n );\n return Object.values(PRODUCT_CATALOG)\n .filter((p) => p.code !== \"accounts\")\n .map((p) => ({\n ...(urls?.[p.code] ? { ...p, url: urls[p.code] } : p),\n accessible: isVega || accessibleCodes.has(p.code),\n }));\n}\n\n// Produtos do app launcher. Time VEGA ve o catalogo inteiro (menos o Accounts,\n// que e o IdP); cliente ve so os codes da claim `products`. Ambos filtram\n// ssoEnabled. `urls` sobrescreve URLs por ambiente.\nexport function getAccessibleProducts(\n claims: AccountsClaims | null,\n opts?: { urls?: Record<string, string> },\n): ProductMeta[] {\n if (!claims) return [];\n const urls = opts?.urls;\n if (derivePersona(claims) === \"vega\") {\n return Object.values(PRODUCT_CATALOG)\n .filter((p) => p.code !== \"accounts\" && p.ssoEnabled)\n .map((p) => (urls?.[p.code] ? { ...p, url: urls[p.code] } : p));\n }\n return parseJsonArrayClaim(claims.products)\n .map((code) => resolveProduct(code, urls))\n .filter((p) => p.ssoEnabled);\n}\n","import type { AccountsClaims } from \"./claims\";\nimport { derivePersona, type Persona } from \"./persona\";\nimport {\n getAccessibleProducts,\n getCatalogWithAccess,\n type CatalogProduct,\n type ProductMeta,\n} from \"./productCatalog\";\n\n// Modelo de dados da casca de identidade (SEM React). O host mapeia isto pros\n// props do <IdentityBar> do @vegait/lyra-ds-v2, adicionando icones/labels/\n// callbacks a partir de `capabilities`.\nexport type IdentityModel = {\n persona: Persona;\n user: { name: string; email: string };\n products: ProductMeta[];\n /** Catalogo completo (menos Accounts) com flag de acesso — pro waffle\n * mostrar tudo e desabilitar o que a persona nao acessa. `products`\n * permanece so-acessiveis por retrocompat (SIG consome hoje). */\n catalog: CatalogProduct[];\n currentProductCode?: string;\n capabilities: {\n manageUsers: boolean; // gestor/vega\n adminConsole: boolean; // vega\n switchContext: boolean; // gestor/vega\n manageNetwork: boolean; // gestor (rodape do launcher)\n };\n};\n\nexport function buildIdentityModel(\n claims: AccountsClaims | null,\n cfg?: { currentProductCode?: string; urls?: Record<string, string> },\n): IdentityModel {\n const persona = derivePersona(claims);\n return {\n persona,\n user: { name: claims?.name ?? \"\", email: claims?.email ?? \"\" },\n products: getAccessibleProducts(claims, { urls: cfg?.urls }),\n catalog: getCatalogWithAccess(claims, { urls: cfg?.urls }),\n currentProductCode: cfg?.currentProductCode,\n capabilities: {\n manageUsers: persona === \"gestor\" || persona === \"vega\",\n adminConsole: persona === \"vega\",\n switchContext: persona === \"gestor\" || persona === \"vega\",\n manageNetwork: persona === \"gestor\",\n },\n };\n}\n"],"mappings":"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","names":[]}
|