Ir para o conteúdo
KAMOUniverse

Changelog

O que há de novo.

Cada melhoria para a plataforma, como ele envia.

  1. · kamo-shared-library

    Repetir os erros do banco de dados Yugabyte espera que um cliente tente novamente

    Aplicando DDL bate com a versão do catálogo, e cada infra- estrutura física ainda segurando o antigo falha sua próxima instrução com SQLState 40001 — "versão de esquema falta de correspondência para a mesa ...: esperado 94, obteve 93". Hibernate não tentar novamente, então ele atinge um usuário como um 500. A última ocorrência produziu 188 deles em toda a frota mais de quinze minutos, e chegou como um relatório de erro sobre um widget: o falhando consulta é quase sempre uma carga de identidade chata que executa primeiro em cada pedido autenticado, por isso qualquer característica grita mais alto é culpado. Não há nenhuma configuração que remova isso. O guia de operações de Yugabyte diz DML concorrente durante DDL "pode usar o esquema antigo, o novo esquema, ou encontrar erros temporários do esquema de incompatibilidade que exigem retries do cliente", e os dois as opções do servidor que estreitam a janela não são configuradas em tempo de execução — verificadas com yb-ts-cli, que se recusa tanto sem - força - assim, mudando ambos os custos reiniciar um banco de dados rodando um mestre e um servidor t. Uma nota anterior nesta base de códigos culpou o maxLifetime de HikariCP e sugeriu A baixar. Isso não teria feito nada: o servidor t executa -- enable ysql conn mgr=true, então os pools Java mantêm conexões LOGICAL em O próprio gerente de conexão de Yugabyte e o catálogo velho vive em física compartilhada backends a piscina não possui. Não custa nada quando nada está errado: retentar é conduzido inteiramente por uma exceção Um aglomerado saudável nunca atira, então o caminho do estado estacionário é uma chamada lambda. Deliberadamente estreito sobre o que vai tentar novamente — uma violação de restrição é o banco de dados dizendo que a escrita está errada, não que foi azar, e tentar novamente transforma um erro rápido em três erros lentos. Resta uma falha inconclusiva Sozinho. O mesmo 40001 também abrange conflitos de serialização genuínos e Yugabyte read reinicia, ambos os quais chegam aos usuários como 500s hoje. Nada o chama ainda; a fiação segue.

  2. · KlusterServices

    Diga se um terminal está funcionando ou esperando por seu membro

    Cada terminal na lista agora carrega `estado`: ocupado, ou esperando. É o uma pergunta que alguém faz de uma janela que não pode ver, e é o que A cor do Hexhead minimizada irá responder. Um SHELL está esperando quando o comando for um shell — `pane current command` é o que o tmux já vê no painel, então isso não precisa de contabilidade e não pode ir Já está. Qualquer outra coisa em primeiro plano é trabalho que o membro começou. pensamento ou ocioso. A sua transcrição responde em vez disso, da última coisa que alguém Na verdade, disse: assistente, stop ration end turn -> respondeu e devolveu: ESPERANDO assistente, para razão tool use -> está executando algo: BUSY usuário -> apenas enviado, nada ainda: BUSY A última linha é quase sempre contabilidade — custo, fechos, operações de fila, snapshots de arquivos, todos adicionados após a resposta — então, lendo-o iria relatar cada sessão ociosa como ocupada. A análise remonta ao último registo de conversas. Desconhecido lê como esperando, deliberadamente: um "ocupado" errado pinta uma janela verde e esconde que precisa de alguém, onde uma "espera" errada só chama a atenção. Isto é... a direcção mais segura para uma luz de estado estar errada. A listagem pede, portanto, ao tmux um oitavo campo. O título permanece ÚLTIMA e a split stays limited; 'pane current command' é um nome de comando nu sem argumentos, por isso não pode carregar o separador. Verificado na máquina, não apenas em acessórios: de doze sessões reais as sete que estavam trabalhando ler ocupado e os cinco que tinham terminado ler espera — e o o caso shell foi verificado com um `bash¿ vivo (esperando) e um `sono' vivo (ocupado). 226 testes.

  3. · kamo-internal

    Escolha o modelo e o esforço antes de iniciar uma sessão de codificador, uma vez

    O diálogo Enviar para IA tem, e os dois são a mesma escolha em vez de dois. Alguém que se fixou em Sonnet em High já decidiu. Re-colheita na outro lugar cada vez é o tipo de atrito que ninguém jamais relataria como um bug e todos se sentem diariamente, então o par é armazenado como uma preferência de UI membro - sobre a pessoa, não o navegador, então um laptop e uma área de trabalho concordar e limpar um navegador não os coloca de volta silenciosamente no Opus. Ele monta o mapa de preferência o launchpad já lê uma vez por carga de página, então querendo que não custa nenhum extra pedido de primeira pintura. Ambas as superfícies podem ser abertas imediatamente — o Centro de Interação é um painel sobre o página está ligada a janela Enviar para IA — por isso é anunciada uma alteração, bem como escrita, e o outro segue sem ser montado novamente. Três coisas que valem a pena chamar: - O diálogo Enviar para IA não re-semeia mais o modelo e o esforço quando abre. Ele Sim, quando eles eram estado local, e deixando que em teria escrito o padrão volta sobre a escolha permanente do membro cada vez que um relatório de erro Foi enviado — exatamente o oposto de se lembrar dele. - Uma preferência armazenada sobrevive ao código que o escreveu, por isso é verificado em vez um modelo aposentado entre lançamentos não deve também Custou ao membro o esforço que ele escolheu. Qualquer coisa não reconhecida cai de volta, que mantém uma seleção de renderizar um valor que não é uma de suas opções — que mostra como uma caixa vazia, e é como alguém descobre sua configuração por ser Desapareceu. - Os selects são nativos, desenhados na paleta. Este painel é pintado de as cores do aplicativo em uma superfície e o emulador na outra, e MUI Selecione renderiza seu menu em um portal que precisaria de toda a paleta passou por ela para evitar uma lista branca saindo de um painel preto. A controle nativo obtém isso de `color-scheme` e traz teclado correto e comportamento do leitor de ecrã com ele. Retomar uma sessão também usa a escolha de pé: escolher uma conversa de volta e escolher um modelo são decisões separadas. Nenhuma nova chave de dicionário — as etiquetas Modelo e Esforço e cada nome de opção são a janela Enviar para IA própria, reutilizada em vez de duplicada para que não possam derivar. 13 de 14 guardas e 5363 testes passam. check-i18n-keys está atualmente vermelho em outro A sessão é de assinatura de voo, nada aqui.

  4. · SecurityService

    Carregue o modelo e o esforço do membro para uma sessão de codificador

    e deliberadamente não examinado aqui. `coder flags` no agente é a única coisa que decide o que uma sessão executa com — seu próprio comentário chama-lhe "o limite de segurança de toda a expedição caminho" — então um segundo vocabulário neste serviço seria uma segunda opinião que poderia discordar com ele, e o que discordava seria o que ninguém era A ler. Qualquer coisa exterior volta como uma recusa com uma sentença o console imprime verbatim, exatamente como um diretório de trabalho desconhecido já faz. A chamada que antecede isto envia.

  5. · KlusterServices

    Deixe uma sessão de codificação ser executada no modelo e no esforço escolhido pelo membro

    para uma nova sessão e para uma retomada semelhante, desde `--modelo' e `-esforço` são bandeiras por sessão de qualquer forma. Eles são a única parte do comando que um chamador pode influenciar, e eles ainda não pode expressar uma bandeira: ambos passam por `coder flags`, o mesmo vocabulário fixo o envio de envio para IA usa, que mapeia um nome em argumentos fixos e levanta em qualquer outra coisa. O modo de permissão não é acessível a partir daqui e não tornar-se um parâmetro. Nomear NEIR é permitido e significa "qualquer configuração do membro diz" — uma resposta melhor do que uma que este agente inventou, e que qualquer Antes disso, isto envia. Nomeando apenas um é recusado: correndo em seu modelo, mas O esforço de outra pessoa não é o que qualquer resposta significava. Ultra Code é xhigh mais uma palavra-chave no MESSAGE, e uma sessão interativa Não tem nenhuma mensagem para o agente colocá-la. É, portanto, executado em xhigh e o membro digita a própria palavra, que é o comportamento honesto em vez de um O silêncio downgrade vestido como outra coisa. 215 testes.

  6. · kamo-internal

    Nomeia um hexhead após a janela que ele representa

    Uma dica de ferramenta do hexhead dizia "User w12" — o id da cabeça, que é o id da janela, num string escrita para avatares de membros. Uma doca de seis janelas minimizadas foi seis etiquetas idênticas, então a única maneira de encontrar o que você queria era abri-las. O título já estava lá: cada desova carrega o título da janela (a loja requer), o menu de contexto já o mostra, e HexHead já tinha um `alt` prop alimentando tanto sua dica e seu nome acessível que nada nunca Passei. Thread `head.title` para baixo através do palco ea mola para ele. Mantêm-no actualizado também. Uma cabeça é gerada com o título que a janela tinha no momento em que foi minimizado, e os títulos continuam se movendo depois disso — um bate-papo renomeado sobre o socket, uma mudança de lista, uma sessão de IA nomeada pelo servidor uma vez que respostas. O barramento de ferramentas agora espelha `tool:title` como `hexheads:title`, e o motor aplica-o da forma como aplica contagens não lidas: absoluto, mesmo mudar, e nunca criar uma cabeça para uma janela que não tem nenhuma.

  7. · SecurityService

    Recusar uma entrada cuja máquina nomeie nenhuma organização

    Tal hospedeiro pode entrar até agora. A escolha do espaço de trabalho não foi possível caminho e conseguiu a adesão sozinho, o que o tornou uma porta onde nenhum dos controlos próprios do inquilino aplicados: regras de acesso e blocos geográficos são por organização, assim decidir (ip, host) só poderia responder "permitido - nenhuma organização possui esta host". Nada foi totalmente ignorado, porque a adesão ainda estava provada e completoSignIn verifica novamente as regras uma vez que um espaço de trabalho é escolhido. Mas a credibilidade verificar-se sentado atrás de nenhuma política de inquilino em tudo, alcançável apontando qualquer DNS nome na entrada, ea escada lockout adicionado ao lado dele não tinha blocklist para aumentar e contar sob um inquilino sintético. Recusado antes das credenciais serem lidas e antes do portão de bloqueio. Ordem é metade do ponto: uma máquina desconhecida não é uma senha errada, por isso a contagem seria caminhar um utilizador legítimo em direcção a um bloqueio sobre o erro DNS de um operador, e Recusar-se aqui significa que os contadores sintéticos nunca são criados. Disse claramente em vez de por trás da recusa de credencial genérica. Que hospeda isto as respostas da plataforma não são um segredo — a Traefik já o conduz — e operador trazendo um novo domínio inquilino que é dito "passe errada" vai gastar A tarde a refazer. Dois esculpidos, ambos deliberados: Hospedeiro local. OrgResolutionService.byHost exclui-o explicitamente, de modo que nunca pode nomear uma organização eo portão faria o desenvolvimento local impossível. É decidido a partir do HOST, espelhando que a escultura existente, NÃO do "endereço do chamador não é público" — cada pedido dentro do cluster Parece que sim, então o dia X-Forwarded-For roading quebra na produção que A versão do teste desligaria o portal através da frota. Loopback Apenas literais; um nome de serviço não está isento. Um interruptor de desactivação, ********** *** *** *** *** envio ligado. Se uma tabela de domínios problema sempre para hosts legítimos resolver, login tem que ser reaberto sem uma realocação — e reabrindo restaura o caminho antigo exatamente em vez de um terceiro comportamento. Um host isento deve manter DEFERRANDO à escolha do espaço de trabalho, não meramente passar Portão. Enviando-o para o caminho resolvido pelo host, em vez disso, quebra-o mais silenciosamente: autenticateO formulário de três argumentos do usuário recusa sem um FQDN resolvido, então "anfitrião desconhecido" teria chegado vestido como uma senha errada. Aquilo foi real. defeito no primeiro corte desta mudança, pego perguntando o que localhost faz Próximo.

  8. · KlusterServices

    Um terminal de codificação usa o codificador de nome dado à conversação

    em execução tinha sido intitulado há muito tempo "Startup aplicação taxa e Harmony ajustamento da conta". Duas coisas separadas estavam a engolir esse nome. ** A listagem.** O título foi escrito uma vez, no bootstrap, como um placeholder. Ele uma conversa alguns segundos dentro e renomeia-a mais tarde se o trabalho acaba por ser outra coisa, então uma cópia armazenada está errada quase imediatamente — o mesmo argumento o resto deste arquivo já faz para ler o tmux e o disco em vez de A manter uma mesa. Custa ~6ms mesmo contra uma transcrição de 205 MB, porque coderSessionIndex lê apenas as duas extremidades de um arquivo e memoiza em (tempo, tamanho). ** A janela.** O 'set-titles' do tmux está desligado por padrão, então a aplicação emitindo- o o tempo todo — o título do painel já estava certo enquanto a janela da ferramenta porque o padrão do tmux iria prefixar cada nome com é o nome da máquina: que iria renomear cada terminal "desktop-1" sobre o nome seu Foi o membro que o deu. de relance e o nome não muda de forma entre a abertura da janela e O mesmo formulário que o SecurityService já utiliza para o etiqueta inicial. Um nome que o MEMBRO digitado ainda ganha e é deixado exatamente como digitado; um nome derivado que escreveu demais, faria com que o renomear campo mentisse. A única exceção é um armazenado placeholder ele é, assim os terminais abertos antes desta mudança começar a derivar em Eles próprios, em vez de precisarem das opções de tmux de alguém. A união vive no /terminals manipulador em vez de dentro de qualquer metade - TerminalManager sabe apenas tmux, codificadorSession O índice só conhece o disco, e nem deve ter que aprender sobre o outro para responder à sua própria pergunta. 212 testes. Verificado contra a máquina ao vivo: o terminal em execução resolve para

  9. · kamo-internal

    Mostrar o bloqueio de entrada como uma regra que não pode ser desligada

    SecurityService agora aplica um bloqueio progressivo de entrada em cada organização se existe ou não uma linha para ela — cinco tentativas livres, então cinco segundos, então Fechaduras de cinco, quinze e trinta minutos, depois um bloqueio IP permanente. Detecção Regras é onde um administrador vai para descobrir o que está protegendo-os, então Tem de o dizer. É a primeira regra nesta tela cujo interruptor está bloqueado, que precisa de mais do que uma entrada deficiente. A fila senta-se primeiro, com um cadeado, um "Sempre em" chip ea escada renderizado somente leitura como chips - porque uma proteção que não pode ser configurado ainda tem que ser legível, e "LOCKOUT LOGIN PROGRESSIVO" sozinho não diz a um administrador nada sobre o que vai acontecer com seus usuários. O botão excluir é ABSENT em vez de desabilitado. Excluir é o outro caminho para desligar uma regra; SecurityService recusa com um 409 de qualquer forma, e um botão cujo único resultado é uma recusa é um botão que reside. O mesmo raciocínio para a janela de edição, que para esta regra mostra apenas a leitura da escada e o alerta Os beneficiários — o único campo que um inquilino possui efectivamente. O servidor ignora o outro campos no caminho para dentro, então renderizando-os ofereceria edições que silenciosamente não Salvar. O nome do interruptor bloqueado se através do slotProps.input. As palavras da fila vivem um elemento irmão, então sem ele um leitor de tela anuncia "checkbox, check" e nada mais — e a dica carregando a razão para o bloqueio não é Atingível dessa forma. inputProps teria sido deixado em silêncio pela MUI Switch; check-switch-aria existe porque isso mordeu este repo antes. Nada aqui impõe nada, e os testes dizem que: Detecção do Serviço de SegurançaRegraTeste Obrigatório. O que está preso aqui é que o o ecrã não mente sobre isso — o interruptor não pode mover- se, o apagar não é oferecido, a escada é visível, e uma regra comum mantém cada controle sempre teve, então o bloqueio é sobre este tipo de regra e não sobre regras de detecção em geral. Chaves do dicionário foram empurradas para o dicionário kamo-tradução primeiro; next-intl mostra um caminho de chave ausente verbatim, e mensagens/ é gitignored aqui, assim que o outros navios de ordem visível tagarelice que uma construção local verde não iria pegar.

  10. · kamo-login

    Mostrar o bloqueio progressivo, por isso um hold-in explica-se

    O servidor agora recusa as inscrições em uma escada — cinco tentativas livres, depois cinco segundos, em seguida, fechaduras de cinco, quinze e trinta minutos, em seguida, um bloco permanente. Sem nada disso, a tela responderia tudo isso com "Usuário inválido ou senha" e um botão que silenciosamente não faz nada, que lê como o site ser quebrado em vez de como um controle de segurança funcionando. Quatro estados, e as diferenças entre eles são o design: Um METER STRIKE aparece sob o campo de senha quando as falhas começam acumulando, dizendo quantas tentativas permanecem antes de assinar em pausas e para Quanto tempo. Alguém que se esqueceu genuinamente de sua senha deve ser empurrado para o link de reset ANTES de serem bloqueados para fora, não depois. A espera de cinco segundos permanece em linha: o botão Iniciar sessão torna-se uma contagem regressiva com um barra drenando através dele. Tirando a forma e guardando para cinco segundos seria mais perturbador do que a espera. Uma fechadura de minutos assume o cartão — um anel que esvazia, uma contagem regressiva mm:ss, e uma fuga de palavras-password reset, porque pela décima falha a senha é esquecido em vez de erro digitado e recuperação é uma porta este bloqueio não Perto. OVERLAYS o formulário em vez de substituí-lo: os campos permanecem montados e desabilitado para que um gerenciador de senhas mid-fill não perca seu alvo. Um BLOQUEIO PERMANENTE não recebe nenhuma contagem regressiva, nenhum anel e nenhum dinheiro para tentar dinheiro. An animação implicando algo está vindo quando nada é seria uma mentira contada Devagar. Diz que a conta não é a coisa que foi bloqueada, porque isso é verdadeiro e é a primeira coisa que a pessoa vai querer saber. Nenhuma política vive aqui. O navegador possui a contagem regressiva e nada mais — um segundo cópia da escada no código do cliente é uma cópia que um atacante pode editar e uma cópia que deriva no momento em que ambos os lados mudam. Este acordo foi mordido exactamente por isso. antes: a verificação de regras de acesso do nó comparou tipos de regras com "whitelist" enquanto o editor escreveu "WHITELIST", nada igual, e ninguém notou. Então a API rotas retransmitem os números do servidor intocados, incluindo o encaminhamento 429 como ele próprio em vez de desmantelá-lo em 400, que iria relatar "mau pedido" para um resposta cujo conteúdo inteiro é quanto tempo esperar. Um bloqueio não abala o campo de senha nem seleciona seu conteúdo. O tremor significa "você digitou a senha errada", e durante um hold a senha nunca foi olhar — culpar o campo seria culpar a coisa errada. Todos os quatro estados renderizados e lidos com marionetista contra servidor enlatado respostas, porque uma compilação verde não prova nada sobre como uma página parece. Redução moção é honrada explicitamente; moção / reação não honrá-lo por conta própria.

  11. · SecurityService

    Bloqueio progressivo de entrada, aumentando para um bloco IP permanente

    Uma senha errada agora custa algo, e o custo sobe. Contado desde o o último log-in bem sucedido do sujeito: as cinco primeiras falhas são livres, o sexto e cada um depois dele espera cinco segundos, e o décimo, vigésimo e Trinta e cinco, quinze e trinta minutos. O quadragésimo coloca o endereço na lista de bloqueio permanente da organização e o e-mail sysadmin. Quem é contado é a parte que vale a pena ler. O assunto é normalmente o (endereço, identificador) PAIR, não metade sozinho. Contar o identificador sozinho deixaria qualquer um que conheça um nome de utilizador bloqueie o seu proprietário do outro lado do mundo; contando o endereço sozinho deixaria uma pessoa atrás de um escritório compartilhado A NAT tranca os colegas. Uma escada só para pares tem um buraco, no entanto — pulverizar uma palavra-passe entre duzentos nomes de utilizador e nenhum par nunca atinge seis — assim, um endereço visto falhando contra mais de dez identificadores DISTINCT torna-se um sujeito em seu próprio direito, e a partir de então cada falha dele conta com um Escada qualquer que seja o nome da conta. O mais duro dos dois governa. Verificado ANTES que a senha é comparada, em cada terminal de suporte de credencial: ambos os caminhos de entrada e o desafio MFA, cujo espaço de seis dígitos tem o seu próprio Escada para que um autenticador confuso não possa gastar o orçamento da etapa de senha. A chamador que ainda pode medir a diferença entre um certo e uma senha errada enquanto trancado fora tem um oráculo de trabalho e um bloqueio que só perde tempo. Falhas são contadas para identificadores que nomeiam ninguém, exatamente como para aqueles que Sim. Contar apenas contas reais faria um nome de usuário errado barato e um direito um oráculo caro, que é um oráculo de enumeração de conta construído a partir da latência. Redis-backed, 30 dias de deslizamento TTL, limpo onde últimoLoginService já selos Um verdadeiro registo. Falha-aberta em cada erro do Redis, correspondente ao AccessDecisionService's doutrina: um lockout que falha fechado em uma infraestrutura inquilino fora da sua própria plataforma. Falhas são registradas com o jogável, não apenas a sua mensagem — um defeito neste caminho é indistinguível de um A falha, e silenciosamente desligaria todo o controle. A quadragésima falha bloqueia o endereço por si só em vez de confiar no Chamador para continuar e escrever a linha da lista de bloqueios. Essa fila fica atrás de 30 segundos. cache do veredicto, e em um host nomear nenhuma organização não há nenhuma linha para escrever em tudo; um controle que depende de seu chamador para ser eficaz é um a posterior O refator desliga por acidente. PROGRESSIVO LOGIN LOCKOUT aparece nas Regras de Detecção como regra que não pode ser desligadas ou suprimidas e cujos limiares não sejam dados sobre os inquilinos — um editável limiar é um interruptor de desligar usando um chapéu diferente. Os beneficiários permanecem editáveis, ou O aviso de bloqueio só poderia chegar ao operador da plataforma. A fechadura vive dentro o serviço, não o controlador: um portão que pode ser alcançado ao redor não é um portão. A linha está materializada no Read, porque todas as organizações já existentes detém as cinco regras originais e nunca alcançaria o ramo sem sementes.

  12. · kamo-internal

    Mostrar a um membro o URI de redirecionamento em seu próprio domínio

    Esta é a tela que toda a mudança é para. Um membro a configurar o Google Espaço de trabalho com o próprio aplicativo OAuth da sua organização vem aqui para encontrar o endereço para colar no console Google — e encontrou api.kamocrm.com, hardcoded no catálogo, para uma organização que tenha verificado sua própria domínio e cujos membros nunca ver o nome de host de Kamo em qualquer outro lugar. O endereço agora vem do servidor, por organização, e é renderizado somente leitura em vez de como uma caixa de texto. Isso não é uma escolha de estilo: nada já leu um valor digitado nesse campo. EmailService, MediaService e VOIPService cada um repete o seu próprio redirecionamento configurado no token Uma URI e uma org digitados aqui foram mostrados de volta para eles e ignorados — e uma org que digitou um que discordou com o que o serviço envia tem um redirecionamento uri missmatch de dentro do Google sem nada nesta tela para Explica-o. Também não é mais enviado ao salvar, então nenhum texto armazenado pode Olhe com autoridade na próxima carga. Cada chamada é feita, não apenas a primeira. Uma Microsoft registro é o aplicativo caixa de correio e o aplicativo de reuniões de equipes; cada metade completa em seu próprio serviço de callback, então Entra precisa tanto e mostrar um deixa o outro a falhar sem nenhuma pista de qual URI foi enviado. O mesmo. aplica-se ao cartão de plataforma, então callbackUrl tornou-se callbackUrls lá também — e Microsoft, Zoho, Zoom, Teams, Meta e Canva ganharam as entradas nunca tiveram, o que deixou um operador de plataforma sem endereço para Registre-se. A lista do catálogo permanece apenas na plataforma e diz isso. Aplicativo de Kamo sempre roda no host da plataforma; a reutilização dessa lista para uma organização seria colocar o hostname da plataforma na frente de um inquilino de marca branca e dizer Para registrar um endereço que seu fluxo nunca envia.

  13. · SecurityService

    Servir cada org a URL de retorno de chamadas em seu próprio domínio

    Este endpoint é onde um membro encontra a string que eles colam no Google console, então é o endpoint que estava errado: retornou apenas o redirecionar a org tinha digitado, e a tela preencheu o espaço com hardcoded api.kamocrm.com — nome do host da plataforma, na frente de um Inquilina de marca branca, para um aplicativo que o inquilino se registrou. callbackUrls é calculado pelo servidor e somente leitura. O anfitrião vem disto. domínio verificado da organização e os caminhos de OAuthCallbackPaths, que é a mesma tabela EmailService, MediaService e VOIPService build o seu próprio redirecionamento de — por isso o endereço mostrado aqui e o endereço enviado no fio estão uma corda por construção em vez de por acordo. Fazer isso errado não tem nenhum sintoma local; ele aparece dentro de um terceiro, semanas depois, como um redirecionamento uri mismatch. Uma lista, não uma string: um registro da Microsoft é o aplicativo de caixa de correio e o aplicativo Teams-meetings, e cada metade completa em seu próprio serviço callback, assim que Entra precisa tanto registrado e a tela tem que dizer isso. Vazio para um provedor cujo callback Kamo não serve — X não tem conexão fluxo, e cada provedor de folha de pagamento completa em uma página kamo-internal na máquina do espaço de trabalho. Esses mantêm seu campo editável em vez de ser entregue um Api de aparência plausível.* endereço nada escuta. OrgDomains.verifiedRootDomain agora delega para o predicado compartilhado para a mesma razão: duas cópias da regra deixaria esta tela e o serviços discordam sobre quais rotas de domínio.

  14. · VOIPService

    Recuar para o nome do próprio host da org para o redirecionamento de Equipes

    Um redirecionamento do org digitado em seu próprio registro ainda ganha totalmente — Microsoft requer o URI reproduzido na troca de token para corresponder ao autorização byte-for-byte, então o que quer que tenha entrado naquele aplicativo Entra é o somente a resposta correta, e uma conexão existente não deve se mover. O que muda é o retrocesso. Uma org em sua própria aplicação sem o redirecionamento armazenado foi obter o hostname da plataforma; agora ele recebe api.<seu próprio domínio>, que é o que sua tela de configurações mostra. Uma org O aplicativo multi-doente de Kamo mantém o host da plataforma, desde que o registro tem um redirecionamento e um endereço de per-org contra ele é uma incompatibilidade. Ambos os controladores VOIP OAuth já encaminhados através deste método, então a org e membro conectar as pernas se movem juntos.

  15. · MediaService

    Enviar o próprio nome de máquina de uma org como o reencaminhamento da reunião OAuth

    A mesma regra que o fluxo da caixa de correio segue agora, para as reuniões Zoom e Teams: uma organização em seu próprio aplicativo registrado esse aplicativo contra api.<seu próprio domínio>, então é isso que vai no fio. O callback é público e sem sessão, por isso tanto a organização como o provedor sai do `estado' — o provedor, bem como a org, porque uma org pode estar em seu próprio aplicativo Zoom e aplicativo Entra de Kamo de uma vez e o Dois têm de obter respostas diferentes. Uma org no aplicativo de Kamo mantém o host da plataforma: esse registro mantém um redirecionar URI e um endereço de per-org contra ele é um descompasso que ninguém pode Consertar de dentro de Kamo.

  16. · EmailService

    Enviar o próprio nome da máquina de uma org como o redirecionamento OAuth da caixa de correio

    Uma organização que trouxe seu próprio aplicativo Google ou Entra registrou que app em sua própria conta, sob sua própria marca, e agora é informado em seu tela de configurações para autorizar api.<seu próprio domínio>. Isto faz o serviço Manda isso. Ambas as pernas passam por um escolhidor, porque eles têm que concordar: o valor sobre o pedido de autorização e o valor reproduzido na troca de fichas deve ser bytes idênticos ou o prestador rejeita o intercâmbio. A chamada de volta perna é pública e sem sessão — o navegador chega do provedor sem sessão de Kamo — então a organização sai do estado, que é por que orgIdFromState existe ao lado do provedorFromState. O portão não é incidental. O registo da plataforma de Kamo tem exactamente um URI redireccionado, no servidor de plataforma; enviar um endereço de per-org contra ele é redirect uri mismatch o org não pode corrigir de qualquer lugar dentro de Kamo, porque eles não possuem esse projeto Google. hasOrgOwnClient é o mesmo question PlatformOAuthClientResolver responde quando escolhe qual cliente id para enviar, para que a credencial e o redirecionamento nunca possam discordar sobre que aplicação está a ligar. Apenas a autoridade é reescrita, então GOOGLE OAUTH REDIRECT URI mantém sua caminho e seu esquema. OAuthRedirectUriTest chama a escolha privada do controlador do que restaurá- lo, e fixa o padrão configurado contra OAuthCallbackPaths — a tabela que a tela de configurações lê. Aquele guarda é... o ponto do arquivo de teste: se os dois derivam, nada aqui falha. Ele falha no Google, semanas depois, para uma organização que copiou uma Pendure um ecrã que já estava errado. Ele também pegou o único bug real nesta mudança: plataformaProviderFor liga o enum, e um interruptor sobre um enum nulo lança em vez de caindo para o seu braço padrão – então um callback cujo estado não iria decodificar levou um NPE no caminho para sua própria página de erro.

  17. · kamo-shared-library

    Endereçar chamadas de OAuth de uma org para seu próprio domínio

    Um OAuth redirecionar URI é mantido por um terceiro. Um membro cola- o em Consola do Google ou da Microsoft, e a partir daí o valor do serviço envia sobre o pedido de autorização e replays na troca de token tem para corresponder ao que eles digitaram, caractere para personagem. Assim, o endereço uma tela de configurações SHOWS e o endereço um serviço SENDS são uma pergunta, e até agora eles foram respondidos por diferentes constantes em repositórios diferentes — com o nome de máquina da plataforma gravado em ambos. Uma organização que tenha verificado acme.com registra seu próprio aplicativo OAuth, em sua própria conta Google, sob sua própria marca, e foi dito para autorizar api.kamocrm.com. OrgApiHosts responde "qual máquina" e OAuthCallback Os caminhos respondem "que caminho", e entre eles são a uma definição SecurityService, EmailService, MediaService e VOIPService todos lidos. O predicado do domínio é aquele que o caminho sign-in já routes on – ativo, alias-less, propriedade verified, ssl confirmado — e cada condição ganha seu lugar aqui por sua própria razão. propriedade verificada porque duplicados através de orgs são legais, então uma linha não verificada enviaria uma chamada de retorno de um provedor, carregando um código de autorização ao vivo, para alguém O anfitrião do outro. ssl confirmado porque `api` é um dos rótulos do SSL a probe cobre, de modo que a bandeira é o que faz api.<domínio> uma máquina com certificado em vez de um navegador intersticial que engole o código. reHost reescreve apenas a autoridade, então um operador que moveu um retorno de chamada na configuração mantém seu caminho e seu esquema, e um valor que não pode ser analisado é devolvido intocado em vez de substituído por um palpite. Um provedor pode possuir mais de uma chamada de retorno: uma única Microsoft registro é o aplicativo de caixa de correio E o aplicativo de reuniões de equipes, e cada metade completa no caminho do seu próprio serviço — por isso a Entra precisa tanto, como apenas de A lista pode dizer isso.

  18. · SecurityService

    Os dados da conta do utilizador pertencem ao seu proprietário ou a um operador

    Uma regra, em um lugar, para os três terminais que escrevem uma conta USUÁRIO: o atualização do membro do perfil, endereço pessoal do perfil e a plataforma Usuários tab. Eles governam os mesmos dados e se derivaram em três respostas diferentes. UserAccountEditPolicy: a pessoa em si, um operador Usuário do sistema, ou um administrador de plataforma segurando MANAGEME USERS / SYSTEM USER — a aba Usuários na /conta. A pré-condição de alto nível de organização acompanha livre, uma vez que PlatformRightsResolver não resolve nada para uma sessão em um inquilino. Duas coisas caem deliberadamente. GESTÃO MEMBROS E GESTÃO MEMBER SECURIDADE já não chegam ao nome legal, o Nome preferido ou data de nascimento. Trata-se de direitos sobre uma conta. cada organização que a pessoa pertence a ações, e um administrador de inquilinos pode editar os modelos de segurança da sua própria organização — para que um inquilino pudesse conceder-se a capacidade de reescrever a identidade que todos veem. O mesmo raciocínio tem Mantive-os sempre fora da senha. Esta foi também a única regra do objectivo por escrito. - (FR) Senhor Presidente, a Comissão dos Assuntos Económicos e Monetários e da Política Industrial, em nome da Comissão do Meio Ambiente, da Saúde Pública e da Defesa do Consumidor, em nome da Comissão do Meio Ambiente, da Saúde Pública e da Defesa do Consumidor, sobre a proposta de directiva do Parlamento Europeu e do Conselho relativa à aproximação das legislações dos Estados-Membros respeitantes aos impostos sobre o volume de negócios e aos impostos sobre o volume de negócios. "A organização atual é dona da conta" se foi. Parece natural. salvaguarda e era um beco sem saída: a plataforma fornece a conta para 77 de 141 e 37 dessas pessoas não são membros da organização que possui a sua conta em tudo — de modo que nenhum espaço de trabalho existiu em que eles poderiam editar o seu próprio nome, nome preferido ou endereço pessoal. Também respondeu ao Pergunta errada para o proprietário, que é uma Pessoa, não uma organização. Prova da a caixa postal está intocada e é a salvaguarda que realmente importa para o endereço. A política resolve as suas armas de operador mesmo quando a conta-alvo não pode ser Lê. Recusar todos num alvo desconhecido soa como falhar fechado e é realmente falhando errado: deixaria uma conta que ninguém poderia corrigir, que é o estado de um operador existe para sair. «isSelf» na actualização dos membros fica por ID-MEMBRO: uma sessão de representação tem se o seu memberID tivesse sido trocado para o alvo, e uma sessão de sudo deveria funcionar como Esse membro sim.

  19. · kamo-shared-library

    Uma regra de detecção que uma org não pode desligar e a letra que envia

    PROGRESSIVO LOGIN LOCKOUT se junta ao DetectionRuleType. Todos os outros valores sobre isso enum descreve algo em que um inquilino opta; este descreve um controle Segurança O serviço aplica-se a cada entrada, quer exista ou não uma linha. A linha existe para que a política seja visível na tela de segurança e seus destinatários de alerta são configuráveis — não para que possa ser desligado. A escada em si não é per-org dados e não vive na tabela. 26 caracteres, assim que se encaixa regra type varchar(30) sem DDL, e a coluna é mapeado EnumType.STRING, assim, anexando relabels nenhuma linha existente. LOGIN LOCKOUT IP BLOCKED é a carta enviada quando um endereço esgota o todo Escada e pousa na lista de bloqueio permanente. É o único alerta nesta família que não é um membro — trata-se de um endereço de ataque — por isso, cada campo que carrega é controlado por atacante e cada um deles usa o fugitivo Gêmeo. O TemplateRenderer não escapa sozinho.

  20. · kamo-internal

    Um operador pode definir um endereço pessoal, e perguntar sobre a conta certa

    Duas alterações no perfil do membro, tanto sobre a mesma confusão: qual pessoa A pergunta está a ser feita. O cartão de e-mail pessoal não é mais auto-apenas. Um operador idóneo e Usuário do sistema pode definir qualquer um, porque o membro que precisa dele alterado é geralmente aquele que acaba de dizer que sua antiga caixa de correio é inacessível — o caso O fluxo próprio do membro não pode servir, uma vez que funciona enviando esse endereço. Deliberadamente não GESTÃO MEMBROS ou GESTÃO MEMBER SECURIDADE: este é um dos três identificadores de login aceita e a recuperação de uma senha escreve para, assim Consolidando-o é levando a conta. A mesma linha que o cartão de senha. O cartão lê através do endpoint do membro-escoberto mesmo no próprio leitor perfil, então há um caminho de código e o SERVER decide se pode ser editado e em que forma. `modo' escolhe o texto, a escrita, e se um senha é pedida — um operador já provou quem eles são, e perguntando Eles por uma senha que eles não têm seria teatro. Três coisas que a variante do operador não deve fazer, cada uma das quais fez primeiro: - fazer o painel pendente. Confirmar, Enviar de novo e Descartar chamada Endpoints Auto-escobertos, então um operador teria recebido três botões que silenciosamente agir em sua conta própria enquanto mostrando o endereço de um colega. - ser suprimido por uma mudança que o membro tinha pendente. Overriding é o ponto; o operador é informado sobre ele em vez disso, incluindo essa configuração O endereço cancela. - oferecer o "onde sua conta vive" explicador do membro. Um operador sabe o que uma conta de usuário é; o que eles não podem ver é que esta escrita não é verificado e não fica quieto, então eles são informados que em vez disso. Separadamente, isSecurityProviderOrg agora significa "esta org possui a conta por trás O MEMBRO SER VIDIDO" e vem do servidor. Costumava ser derivado do navegador da própria conta do READER, que é um fato sobre quem está olhando: um administrador com direito a fixar o nome jurídico de um colega pode ser recusado porque sua própria conta veio de outro lugar, e aquele que não tinha direito Pode ser oferecida a caixa. Para um membro no seu próprio perfil as duas leituras coincidem, por isso nada sobre o auto caso muda. O banner que diz "sua conta é gerenciada por X" mantém o leitor responder, porque é a única coisa aqui genuinamente sobre o leitor — e agora renderiza apenas no seu próprio perfil. Contar as vidas de alguém em outros lugares enquanto eles estão olhando para o registro de um colega responde a uma pergunta que eles Não perguntei. Seis testes fixam o portão como um limite, o mais afiado é que um administrador MANAGEME MEMBERS e MANAGEME MEMBER SECURITY não pode ver nem editar A morada.

  21. · SecurityService

    Deixe um operador deus e o usuário do sistema definir o endereço de alguém

    O endereço pessoal era só para si. É também o endereço que um administrador tem para ser capaz de corrigir — um membro que perdeu a caixa postal por sua conta não pode provar o novo, que é exatamente o caso do próprio caminho do membro não pode servir. Quem: um chamador god-ELIGÍVEL, ou o usuário do sistema da plataforma. Deliberadamente NÃO GESTÃO MEMBROS OU GESTÃO MEMBER SECURIDADE. Este endereço é um dos três identificadores de login aceita e a recuperação de uma senha escreve para, sendo capaz de o definir está a ser capaz de ter a conta — a mesma linha PasswordChangeController desenha, pela mesma razão. Elegibilidade é lida através SessionPlatformFacts em vez de alcançar `GD', porque esse analisador existe precisamente assim que a elegibilidade e uma janela OPEN deus-mode não pode ser confundido. O membro alvo deve estar na própria organização do chamador, como a senha endpoint requer. O que NÃO se aplica é a regra do provedor de segurança: existe para parar um inquilino mudar como alguém se inscreve para outro, e um operador deus e o usuário do sistema são identidades da plataforma em vez de um inquilino. Mantê-lo. deixaria a capacidade inutilizável do espaço de trabalho um operador é realmente Em posição. Nenhuma viagem de ida e volta de verificação nesta via, e o endereço está marcado como UNVERIFIED — ninguém o provou, e deixar um endereço escrito herdar a posição verificada de O que substituiu faria da bandeira uma mentira. Unicidade dentro do fornecedor ainda mantém, porque é um identificador de sinal no entanto foi escrito. A aviso para a caixa de correio velha ainda vai, e importa mais aqui do que no membro caminho próprio: este é o caso em que o titular da conta não iniciou a alteração. Tudo o que o membro tinha pendente está cancelado, então o link de confirmação de ontem não pode anular silenciosamente a correcção. O usuário do sistema pode agora chamar este controlador — administrando outras pessoas A questão é a contabilidade. Ainda pode nunca ser o TARGET. /context reports isGodEligible e isSystemUser para que o console possa decidir o que para oferecer. Nenhum deles é dedutível: o primeiro deve vir através do parser, e a segunda é uma coluna em nenhuma sessão em tudo, por isso sem ele o Usuário do sistema abriria um perfil e não seria mostrado o cartão a que tem direito utilizar. Ambos ampliam uma tela; cada escrita os re-deriva.

  22. · KlusterServices

    Orçamento dos últimos quatro serviços para ganhar uma segunda réplica

    BillingService, EmailService, KamoLOS e SecurityService agora executar dois pods, cada um tendo colocado sua Efeito compartilhado previsto varre atrás de uma locação distribuída primeiro. Entre eles que cobrem o trabalho onde correr duas vezes teria sido mais caro: cobrar um cliente, debitar uma conta bancária, Enviando uma campanha, e revigorando uma bolsa OAuth.

  23. · SecurityService

    Bloqueie as varreduras compartilhadas e execute duas cápsulas

    Dezesseis dos dezessete exames agendados do Serviço de Segurança têm um efeito partilhado e agora toma um nome locação distribuída antes de correr. Não há nenhum ShedLock em qualquer lugar nesta plataforma, então a réplica a contagem foi o que os fez corretos — este serviço teve o trabalho mais programado na frota e foi Portanto, o mais firmemente preso a uma cápsula. Os que valem a pena nomear: Duas cápsulas que refresquem o mesmo subsídio podem invalidar o novo token um do outro e desconectar o calendário BulkExportRunner.pollForWork dois pods alegando que as mesmas linhas em fila correriam o mesmo EHR/PHI exportação duas vezes Verificação de Domínio Observador muda propriedade verificada, que decide qual máquina rotas para as quais org DocReminderSweep envia lembretes de documentos para mutuários LeadLockSweeper poderia liberar um bloqueio outro pod apenas concedido ************* é um @Component aninhado dentro de uma @Configuração, então tomou a locação à mão em vez de através da mesma edição mecânica que o resto. Quatro testes agora exercitam o corpo bloqueado diretamente (sweepLocked, reverifyConfirmedLocked, polnForWorkLocked). Eles chamaram anteriormente o ponto de entrada agendado, que agora pede um SingletonTaskRunner para uma locação que nunca concede — então cada afirmação neles teria passado contra um corpo que nunca fugiu. Em AccessRuleService e OrgObjectStorageSweep o campo injetado é declarado ÚLTIMO: aqueles utilizados Lombok's @RequiredArgsConstructor, que constrói sua lista de parâmetros em ordem de campo, então colocá-la em qualquer outro lugar silenciosamente reordena os argumentos existentes do construtor. réplicas 1 -> 2. Verificado em uma árvore de trabalho isolada fora de origem / principal porque este checkout atualmente carrega o refator OrgNetworkRowBuilder em andamento de outra sessão, que não compila; com somente estes arquivos aplicados o serviço constrói e sua suíte é verde além de duas falhas que reproduzir de forma idêntica na origem/principal (marcas EndpointRatchet não autenticadas UserAccountController #verifyByToken, que não faz parte desta mudança).

  24. · kamolos

    Bloqueia todos os trabalhos que movimentam dinheiro, e executa duas cápsulas

    Kamolos correu um pod e seus dez trabalhos de cron estavam corretos apenas por causa dele. Não há nenhum ShedLock em qualquer lugar nesta plataforma, então uma segunda réplica teria executado cada um deles duas vezes: CONTAS BANCEIRAS DOS DEBITANTES DO TRABALHO JurosAccrualJob acumula juros sobre empréstimos ao vivo — duas vezes é cobrado juros duas vezes DeclaraçãoGeneraçãoJob duas declarações por um período LembreteDispatchJob dois lembretes de pagamento YearEndTaxJob dois arquivos' no valor de papelada por mutuário além de expiração da oferta, delinquência, avanço de resfriamento, agendamento de lembretes e reconciliação Cada um agora leva um nome alugado através de SingletonTaskRunner antes de fazer qualquer coisa. **************** não está deliberadamente trancada. Ele baixa a lista SDN OFAC e substitui um conjunto mantido na própria memória deste pod, então ele tem que correr em todos os lugares — bloqueando-o iria sair cada cápsula, exceto o locatário, que analisa os requerentes contra uma lista de sanções EMPTY, o que é pior do que a duplicação que evitaria. réplicas 1 -> 2.

  25. · EmailService

    Bloqueie as varreduras compartilhadas e execute duas cápsulas

    Nove das dez sondagens agendadas do EmailService têm um efeito partilhado e agora fazem um contrato de arrendamento nomeado antes Correndo. O mais consequencial é CampaignDispatcher: em dois pods sem bloqueio, cada destinatário de cada campanha em execução teria recebido uma cópia. LembreteSchedulerService é o mesmo Forma para reuniões de lembretes, e ************* para notificações snoozed. O décimo, ************* não está deliberadamente trancado. Anda. as caixas de correio vigiadas por clientes conectados a esta cápsula e cutuca os que nada está empurrando, então tem que correr em toda parte — o bloqueio congelaria o crachá não lido para cada membro cujo WebSocket pousou em uma cápsula que não é o arrendatário. @Transactional está agora na embalagem agendada e no corpo bloqueado no LembreteSchedulerService e SyncService. O exterior é o que realmente se aplica (o corpo é alcançado através de um: referência, que nunca passa pelo proxy da Primavera); o interior é declarado porque esse é o método que emite a consulta @Modifying, que é o que a catraca de arco lê — e a catraca capturada Exactamente isto quando a anotação estava apenas na embalagem. réplicas 1 -> 2. 590 testes, uma falha pré-existente não relacionada a esta alteração * **************** falha idênticamente na origem/principal).

  26. · BillingService

    Fechem todas as buscas e executem duas cápsulas

    BillingService correu um pod e suas sete varreduras programadas estavam corretas apenas por causa dele. Ali. é nenhum ShedLock em qualquer lugar nesta plataforma, então uma segunda réplica teria executado cada um deles duas vezes um tick: **************** submete o uso medido ao provedor de pagamento submetido duas vezes, o cliente é cobrado duas vezes DunningSweep retries falhou pagamentos e e-mails sobre eles StorageAutoExpandSweep compra armazenamento em nome do cliente, e cobra TrialExpirySweep termina testes e move assinaturas sobre Caixa de CorreioBillingReconcilier / PbxBilling Luta de reconciliação pelos mesmos itens de assinatura StorageSnapshotSweep conta duplamente a figura de uso noturna de cada org Cada um agora leva um nome alugado através de SingletonTaskRunner antes de fazer qualquer coisa. StorageSnapshotSweep é a única exceção em forma: sua varredura() também é chamada de StorageUsageController quando um operador pede um instantâneo agora, e retorna a contagem de linhas para o resposta. Assim, a anotação @Scheduled mudou-se para uma nova agendadaSweep() que toma a locação, e varrance() em si é intocável e ainda diretamente callável — o pedido explícito de um operador não deve ser silenciosamente ignorada porque outra cápsula acontece de estar no meio da varredura. réplicas 1 -> 2.

  27. · KlusterServices

    Orçamento os seis serviços que acabaram de ganhar uma segunda réplica

    AIService, KBService, EsigService, VOIPService, DocsService e TranslateService agora executam dois pods, Então um dreno de qualquer nó deve expulsá-los um de cada vez ao invés de ambos de uma vez. Os cinco primeiros chegaram lá colocando os seus efeitos partilhados programados para trás de uma distribuição location; TranslateService não precisava de bloqueio algum, porque seu método agendado atualiza um cache na própria memória da cápsula e é suposto correr por todo o lado.

  28. · TranslateService

    Executar duas cápsulas

    O único método programado aqui, povoa um mapa guardada na memória desta cápsula. É suposto correr em cada cápsula, não há nada compartilhado para um segunda réplica para duplicar, e ele deliberadamente não obtém nenhuma trava — bloqueando-o iria deixar cada cápsula mas o locatário com uma tabela de idiomas vazia. Nada mais neste serviço tem estado entre pedidos.

  29. · DocsService

    Bloqueie as varreduras compartilhadas e execute duas cápsulas

    Cada varredura @Scheduled aqui cujo efeito é compartilhado agora leva um nome de locação distribuída através SingletonTaskRunner antes de fazer qualquer coisa, então ele corre uma vez através da frota em vez de uma vez por pod. Essa foi a única coisa que manteve este serviço em uma réplica — não há nenhum ShedLock em qualquer lugar Esta plataforma, então a contagem de réplicas foi o que fez as varreduras corretas. @Transacional e amigos permanecem no método EXTERIOR onde presente: Primavera aplica-los com um proxy, e o método interno é alcançado através de um:: referência, que nunca passa por um. Movê-los para dentro deixaria a varredura silenciosamente não-transacional. réplicas 1 -> 2, com um PodDisruptionBudget em KlusterServices para que um dreno de nó espere.

  30. · VOIPService

    Bloqueie as varreduras compartilhadas e execute duas cápsulas

    Cada varredura @Scheduled aqui cujo efeito é compartilhado agora leva um nome de locação distribuída através SingletonTaskRunner antes de fazer qualquer coisa, então ele corre uma vez através da frota em vez de uma vez por pod. Essa foi a única coisa que manteve este serviço em uma réplica — não há nenhum ShedLock em qualquer lugar Esta plataforma, então a contagem de réplicas foi o que fez as varreduras corretas. @Transacional e amigos permanecem no método EXTERIOR onde presente: Primavera aplica-los com um proxy, e o método interno é alcançado através de um:: referência, que nunca passa por um. Movê-los para dentro deixaria a varredura silenciosamente não-transacional. réplicas 1 -> 2, com um PodDisruptionBudget em KlusterServices para que um dreno de nó espere.

Seu universo está esperando.

Comece gratuitamente em minutos.Adicione produtos sempre que estiver pronto — sem migração, sem novos logins.

Gratuito para sempre — não é necessário cartão de crédito