Changelog
Ce qui est nouveau.
Chaque amélioration apportée à la plateforme, à mesure qu'elle est livrée.
· kamo-internal
Un "pourquoi ne puis-je pas accepter?" l'annulation sur la barre de filtre
Alignement à droite sur la barre de filtre /chef, portant l'icône de la pavé Leads avec la même emblème interdit - donc la chose sur la navre qui dit "vous êtes bloqué" et le Ce qui dit ici, "voici, c'est pourquoi" est visiblement une déclaration. Seulement rendu alors que le membre est effectivement bloqué. Ce n'est pas un filtre qui se trouve être vide, c'est un état qui existe ou non, donc quand le L'interdiction autorise un événement d'acceptation-porte en temps réel, ou un rafraîchissement après le dernier note a été écrite - le contrôle disparaît et les filtres reviennent sur leur qui est propriétaire. Un effet laisse tomber l' neutralisation lorsque cela se produit : le laisser secoué serait brun de la grille sur un zuid IN ()- correspondent à rien, avec les filtres encore grisés et aucun contrôle visible pour les remettre en marche. Pressé, il OVERRIDES plutôt que se rétrécit. buildLeadGridQuery revient très tôt bœuf, donc pas d'onglet de marché, d'onglet d'état, d'agent, de date ou de terme de recherche s'applique. C'est délibéré: les pistes de blocage sont dispersées à travers n'importe quel les marchés et les statuts dans lesquels ils se trouvent, et se croiser avec la barre Montrez un sous-ensemble en lisant la liste dans son ensemble - exactement la mauvaise chose à dire Quelqu'un essayant de se débloquer. Un ensemble vide demande 'uid'0' plutôt que abandonnant la contrainte, de sorte qu'elle ne pourra jamais s'étendre à l'organisation. Les onglets d'état et chaque contrôle sur la barre sont grisés et inertes pendant qu'il est allumée, parce qu'une barre qui regardait encore en direct serait couché sur ce qui a choisi le rangées. La bascule elle-même est exclue par attribut de sorte qu'elle reste pressable, et le Les boutons d'action à côté des onglets ne sont pas des filtres donc ils restent en direct. Réinitialisations de radiomessagerie sur chaque bascule - l'ensemble de résultats est différent et l'ancien numéro de page signifie Rien contre. Off, le bouton pulse: c'est la seule chose sur la barre qu'un membre bloqué doit Remarquez, puisque c'est la raison pour laquelle leurs pistes ont cessé d'arriver. Sur, la grille elle-même est le signal et l'animation serait du bruit. Les distinctions honorifiques préfèrent la montée en puissance.
· SecurityService
Liste, renommer et terminer les terminaux d'un membre
ET DÉLÉTER et PATCH sur /terminaux/-id. Chacun d'entre eux résout le compte Linux à partir de la SESSION DE PROPRE APPEL et n'obtient aucun nom de compte à l'agent provenant de la demande. Un membre peut Par conséquent, il ne voit jamais jamais, renommer ou mettre fin à leurs propres terminaux - il n'y a pas d'id ils pourrait fournir qui atteindrait celui de quelqu'un d'autre, parce que le compte ne fait pas partie de ce qu'ils fournissent. Une machine inaccessible répond 200 avec une liste vide et 'non joignable: vrai plutôt qu'une erreur: "la machine de développement est en panne" est un fait sur la machine, pas une défaillance de la question, et la console peut le dire où une page d'erreur pourrait Ne dites rien. C'est la même règle DesktopSsoController suit. Renommer une session qui s'est terminée est un 404 avec une phrase - le statut honnête pour "vous avez renommé quelque chose qui n'est plus là", qui après un redémarrage est chaque terminal par le membre.
· KlusterServices
Liste, renommer et terminer les terminaux d'un membre
GET/terminals?user-X, POST/terminals/-id-/kill, POST/terminals/-id-/title. Il n'y a pas de place à cette disposition, et c'est la conception plutôt qu'un raccourci. Le serveur tmux sur la machine est le registre: les terminaux d'un membre sont exactement les sessions qui existent, donc une qui finit cesse d'être listée avec rien pour Réconcilier, et un redémarrage - qui prend le serveur tmux avec lui - vide la liste par elle-même. Une table devrait être tout à fait dit, et serait faux à tous les Il ne l'a pas été le temps. Titres personnalisés en direct dans une option utilisateur de type tmux sur la session, donc un titre a la même chose la durée de vie au nom de l'enveloppe. Les caractères de contrôle sont dénudés avant stockage: un titre est rendu dans une liste, et une séquence d'évacuation en une repeuplement serait repeuplé écran autour d'elle - le strippage est aussi ce qui maintient le séparateur de champ hors du valeur, qui est ce qui fait l'analyse de la liste en la scindant. Les titres sont les suivants: a été passé en un seul élément argv, jamais à travers une coquille. "Pas de serveur tmux" est une liste vide, pas une erreur. C'est l'état de la machine après un redémarrage, c'est-à-dire précisément quand le membre a besoin de la liste pour dire "rien ici" plutôt que d'échouer. 20 essais: la forme de la liste et son ordre, sessions non titre notées nulles plutôt que "", les sessions de cet agent n'a pas créé de rester invisible, malformé et les rangées non numériques étant sautées plutôt que fatales, tuer étant idémpotents, titres dépouillés/tronqués/désinsclus et titres contenant des métacaractères de coquille arriver comme un élément argv. Convertit également la sélection de la pompe contre un descripteur fermé sous celle-ci - le même hang-up ordinaire terminant le chemin recv déjà manipulé. 131 essais.
· kamo-internal
Un raccourci de mot de passe dans le héros, et une porte plus étroite
Deux moitiés du même sujet. Le raccourci. Changer votre mot de passe était trois pièces plus loin derrière le rail. la seule chose que la disposition de la pièce a rendu vraiment plus difficile à atteindre que le vieux glisser, et c'est le contrôle le plus conséquent du compte. Le héros maintenant le porte, délibérément PAS comme une troisième pilule de verre: les deux à côté sont destinations, c'est une action, donc elle est solide. En cas d'abscisse multiple il devient ambre et le dit, parce que c'est le moment où l'invite vaut la peine fabrication. Il circule à travers le même chemin de focalisation que la palette de commande utilise, donc il s'ouvre la salle d'accès ET fait défiler la carte de mot de passe en vue. Cette voie est maintenant une fonction partagée par la palette, l'anneau de résistance et ce raccourci, au lieu de trois qui pourraient dériver; les segments de l'anneau ont déjà nommé le champ qui les répare et l'utilise maintenant. PasswordSecurityCard n'est pas un ProfileCard, donc son enveloppe porte l'ancre de défilement. La porte. La fonctionnalité ne montre plus la carte de mot de passe sur le dossier de quelqu'un d'autre - seul le membre lui-même ou un dieu éligible spectateur. C'est la moitié d'AFFICHEUR; la moitié qui importe est expédiée dans SecurityService 197b591, qui retourne 403 pour la même condition. Un droit enlevé d'un écran est un écran d'arrêt, pas un contrôle de sécurité. Les clés du dictionnaire ont d'abord atterri en kamo-traduction-dictionnaire 982c1f62. Vérifié: épreuve npm (14 gardes et 5 139 tests), tsc --noEmit, prochaine construction.
· kamo-internal
Emblème de nav interdit, assignez-vous à moi-même et masque de contact dissimulé
L'icône de la navigation de Leads dit quand vous ne pouvez pas l'accepter. ils n'ont pas travaillé obtient un emblème de bloc rouge au-dessus de l'icône Leads et une infobulle nommer ce qui est bloqué, pourquoi, et quoi effacer. Fabriqué par /leads/réseau disponible et gardé en permanence par un nouvel événement de portage d'acceptation sur le socket crédit/assignation la charge utile ne transporte qu'un membre id, donc chaque navigateur ignore les autres et réassuremment le serveur pour le sien. Montré à n'importe quel membre qui peut voir des pistes, pas seulement des détenteurs de crédit: depuis un Le plomb libre pour tous peut maintenant être auto-recruté, la porte les gouverne aussi. Le le point de disponibilité ne peut que créditer, de sorte que les deux déclarations restent séparables vous pouvez être empêché d'accepter alors que les pistes sont assis là, et ceux-ci sont différentes choses à dire. «Tout statut est nommé la façon dont CETT l'orgmente le nomme. /chefs/avis disponible et correction de l'exemplaire de la page de détail Nouveau plomb/remord de ferme frais par utilisationStatusLabels: les étiquettes sont remplaçables sur/décantes/caracles/crm, et dire à un membre de déplacer une avance "Nouveau lead" quand son org l'appelle quelque chose d'autre ordre un statut qu'ils ne peuvent pas trouver dans le cueilleur. Le ou les pistes/livres de l'avis sont divisés en deux raisons - les pistes doivent une note, les pistes dues à un changement de statut - parce que fusionnée en une liste, elles lisent en tant que pile indifférenciée et le membre doit ouvrir chacun pour apprendre ce qu'il veut. Un plomb en échec est listé une fois, badgé. « Assieds-toi-moi, se trouve sous Réattribution à chaud sur une avance non attribuée. Offert sur une Free-for-all mène à toute personne qui n'est pas interdite actuellement, et à toute conduite non affectée à un détenteur d'ASINSG-LEADS. La réponse porte le dos de l'avance non masqué, donc le mettre en flips d'état assignedToMe, recalcule la décision de masquer MATÉNUÉE, et révèle les coordonnées sans recharger. «Les impulsions de contrôle de l'état» alors que le plomb est à moi et qu'il reste chez New Lead ou Farm Fresh - c'est le contrôle qui le répare, et l'en-tête est lu longtemps avant une infobulle de la pavé. Les distinctions honorifiques préfèrent la montée de la tension. «Les informations de contact massées sont obscurcies, non blanchies. ContactObfuscator exactement, faisant valoir les mêmes chaînes, parce que le Le relais de tête en temps réel est livré à un DTO entièrement non masqué à chaque abonné de l'organisation et le navigateur est la seule chose qui se trouve devant lui. Un champ blanc se lit comme suit : car "ce pas de point de vente n'a pas de courrier électronique", ce qui est une déclaration différente et erronée. Le filtre /leads Unassigned est offert à tout le monde. VOIR-UNASSIGNED-LEADS Rend le libre pour tous non attribué en tête ce membre peut prétendre, et l'étiquette le dit plutôt que l'option qui signifie silencieusement deux différentes choses. Le client ne force plus l'affectation -ASSIGNED pour ceux - la surface du serveur est plus large que celle-ci aujourd'hui, et l'envoi d'ASSIGNED clips exactement les lignes que ce changement existe pour montrer.
· SecurityService
Servir la porte d'acceptation élargie, ajouter l'auto-assignation et fermer deux contournements de masque de contact
«Points de fin de route pour la nouvelle porte». /chef/réseau disponible et/ou têtes/disponibles énumérait maintenant les deux raisons pour lesquelles un membre est bloqué - les pistes doivent un billet depuis qu'ils ont été et conduit toujours à leur état d'admission - avec les pistes elles-mêmes et la formulation d'état SYSTEME plus ids, de sorte que le navigateur peut résoudre le problème de l'ordre des étiquettes personnalisées avant d'afficher à qui que ce soit la raison pour laquelle elles sont coincées. est conservé en tant qu'alias du nouvel « internat », de sorte qu'un navigateur continue d'exécuter le Le paquet précédent continue de travailler dans le cadre du déploiement. La porte est évaluée pour quiconque peut voir des pistes, pas seulement pour les membres qui détiennent SPEND-RECEIVE-LEAD-CREDIT: un membre qui ne peut prétendre qu'à titre gratuit pour tous est soumis à la même discipline et leur navigation doit pouvoir le dire. Le Le scannage de la réserve de crédit en dessous nécessite toujours le droit de crédit. Le ou les chefs de file est un terme à l'autre. Il rend le plomb L'appelant est son cessionnaire au moment où le serveur répond ce qui permet à la page de détail de révéler les informations de contact sans rechargement. «Un nouveau sujet NATS, publié lorsqu'une note atterrir sur une piste, lorsqu'un statut change, et des deux côtés de chaque cession changement. Le relais de MediaService s'abonne déjà à security.leads. sujets à des sujets de manière générique, de sorte qu'il n'a pas besoin de changement. La charge utile ne transporte que un membre id: la réponse de la porte dépend de l'ensemble du livre de ce membre, donc il y a rien d'utile à mettre sur un sujet à l'échelle de l'ordre, et un sujet que chaque membre reçoit est le mauvais endroit pour tout ce qui vaut la peine d'être retenu. «Deux contournements de masque de contact, les deux vérifications trouvées où les détails d'une sonde peuvent être consultés. atteindre un navigateur: - GET/leads/---------------------------------------------------------- Changement de champ log est un enregistrement complet de chaque valeur qu'un champ a jamais détenue, de sorte qu'il est retourné le courrier électronique et les numéros de téléphone que le masque de l'adjecteur prend - et pas seulement le actuels, tous les précédents aussi. Il comporte maintenant les mêmes deux décisions que getLeadById, et LeadHistoryContactMask dissimule les rangées porteuses de contact. L'historique de l'état d'avancement, de la cession et du montant des prêts n'est pas modifié: les coordonnées, pas la piste d'audit. - GET/leads/callback-context/-d'id' a expédié une adresse e-mail et deux téléphones numéros pour tout rappel dans l'orge, non gêné. Un rappel id était un moyen de lire les coordonnées de tout chef de file d'initiative d'un collègue. Le masque de lecture ne blanc plus le contact champs, il les obsure - donc un filieux masqué contient maintenant des cordes d'apparence réelle Cela persisterait parfaitement. La bonne hiérarchie rend cela difficile à la portée, mais "dure à atteindre" n'est pas une garantie et le mode de défaillance est silencieux corruption du numéro de téléphone d'un client. «Clivance de la grille.) Sans VUE-UNASSIGNE-LEADS le plancher de la tête devient "mon leads plus des pistes libres non attribuées " plutôt que "mes sondes", et un Un lead free-for-all n'est pas attribué peut être ouvert et son histoire lisez - une ligne que vous pouvez voir mais ne peut pas s'ouvrir est un bug. La lecture de la CORRESPONDENCE sur l'un d'eux est différente questions et LeadCommsReadGate lui répondent toujours avec VIEW-LEAD-CONTACT-INFO-OTHERS; le champ d'application du réseau commun maintient délibérément le plancher plus étroit, avec un commentaire disant Pourquoi les deux diffèrent-ils maintenant.
· kamo-shared-library
Élargir la porte d'acceptation, obscurcir les informations de contact masquées, laisser libérer-pour toutes les sondes
Trois modifications ont trait à l'élément central de l'affectation des chefs de file. «L'autorisation d'acceptation pose maintenant deux questions, sur chaque plomb assigné.» LeadAcceptEligibilityService remplace la porte de commentaires qui a vécu à l'intérieur CreditLeadEnquitationService. Un plomb bloque son support de prendre un autre quand soit il n'a pas de note d'eux écrit SIN en raison de ce qui leur a été assigné, soit il est toujours assis à Fresh and New Lead / Farm and Farm Fresh. Les deux moitiés ferment un trou. L'ancienne règle comptait n'importe quelle note jamais écrite, donc une piste qui est revenu à un membre transmis sur une note de leur précédent passage avec elle. Et il ne regardait que les pistes acquises par le système d'auto-assignation, qui ont quitté toute autre route - l'affectation manuelle d'un gestionnaire, une importation, une auto-réclamation - comme moyen d'accumuler des pistes intactes avec la piscine encore ouverte. La règle est deux requêtes basées sur le paramétrage quelle que soit la taille du livre du membre: affectations actuelles, puis un agrégat MediaObj groupé sur leur flux guids. Élargir la portée de chaque affectation a rendu l'ancienne boucle de requête par le plomb inabordable - c'est la forme qui a rendu la grille /le têtes lente, et cela s'allume chaque rendu des pistes nav pour chaque membre inscrit. Les statuts de blocage sont nommés explicitement dans LeadStatusType plutôt que dérivé de isAllowSwitchBack. Il se trouve que ces deux sont les seuls statuts portant ce drapeau, mais il répond à une question différente, et un statut futur marqué le même dans une certaine mesure, il ne faut pas commencer silencieusement les acceptations. L'appariement se fait sur le système stocké les descriptions, donc les étiquettes d'état personnalisée d'une gisure n'affectent jamais la règle. Les informations de contact massives sont obscurcies plutôt que coupées. transforme (555) 555-5555 (555) 555-55, snadjafinia.gmail.com en (555) s.gmail.com, et 123 Main St dans la rue principale. Un champ blanc est indistinguable de celui que personne n'a rempli, de sorte qu'un téléspectateur restreint ne pouvait pas Dis "il y a un nombre ici, vous ne pouvez pas lire" à partir de "ce pas de plomb n'a pas de numéro" et le personnel a poursuivi la deuxième lecture. Victité, code postal et pays survivent maintenant sur la même base, l'État l'a toujours fait: assez grossier pour identifier un doublement, Inutile d'atteindre quelqu'un une fois que le numéro de la rue aura disparu. Date des séjours à la naissance absent; aucune forme partielle n'est à la fois reconnaissable et sûre. Le navigateur est exactement en miroir. LeadRealtimePublisher fans complet DTO à chaque abonné org avec aucune projection par bénéficiaire possible. Les suites Java et les suites les plus vives affirment les mêmes cordes de sorte que les deux ne peuvent pas s'écarter inaperçus. «Les pistes gratuites non attribuées à tous sont visibles et susceptibles d'être invoquées.» - revendique une avance spécifique non attribuée. Libérez-tout est la porte ouverte et porte la porte d'acceptation avec elle - sinon il serait la manière dont elle existe à côté de la discipline et des menthes/dépenses Son propre crédit exactement comme l'accepteNextLead, donc Max Daily Spend le plafonne toujours. ASSIGN-LEADS est la porte surélevée: n'importe quelle sonde non attribuée, pas de porte, pas de crédit. L'octroi de licences est une contrainte légale et aucune des deux portes ne lui renonce. Gains de LeadGridQuery et tourner la grille plancher d'autorisation de "chefs affectés à moi" en "chefs qui m'ont été assignés, plus Tout ce qui est vraiment à saisir". Se cacher des pistes gratuites non réclamées à tous de Tout le monde sans VOYAGE - NE SOUS-LÉADS LÉS a laissés en théorie et incommodant dans la pratique.
· kamo-internal
Drapeaux sur les langues et interdiction de copier les listes de plates-formes
Complète c20bac57. Les langues portent maintenant leur drapeau, le même que celui que le commutateur NavTop montre et à partir de la même source - la valeur fermée ainsi que chaque ligne du menu. Se montrer là-bas a mis en évidence le vrai problème: options.ts a augmenté les copies privées de quatre listes que la plate-forme est déjà propriétaire, et c'est ainsi que la page qu'elle a remplacée a également travaillé. Les langues étaient une copie retapée sans codes de pays, donc un drapeau n'était pas même possible. Maintenant app/lib/languages.ts, que le commutateur NavTop et le traducteur de chat partage déjà. Les devises étaient une graine de 34 places contre la plate-forme d'une part, donc a les membres payés en naira ou les shekels lisent leur propre monnaie comme un code nus sans symbole ni nom. Maintenant app/constants/currencies.ts. Les fuseaux horaires ont été retapés à partir des 27 mêmes noms. Maintenant dérivé de La carte complète, donc le cueilleur ne peut pas offrir une zone que rien ne peut résoudre. :: La localisation du travail conserve ses valeurs, mais elles sont maintenant vérifiées par rapport à la Java enum par essai. Le statut d'équipe reste une liste explicite à l'intention: Le miroir TypeScript est STALE et manque CONTRACTS-SENT, donc en le dérivant de Il y aurait silencieusement un membre du statut auquel les membres sont vraiment appelés à abandonner. Le Java enum a neuf; une épingle d'essai toutes les neuf. Les rangées de fuseaux horaires montrent maintenant l'heure où il est là. Vingt-sept noms enum avec le soulignement supprimé est une liste que vous devez déjà connaître la réponse à lire; le temps est la chose qui est choisie, donc c'est la chose montrée. Correction également d'une réclamation que le premier commis n'a pas donné livraison: Consulte préfère-réduction-mouvement par lui-même, donc la pièce enchaînée et l'épargne bar animée quel que soit le réglage. MotionConfig réduitMotion-"utilisateur" Les deux couvrent désormais les deux; les pièces pilotées par le CSS portaient déjà leurs propres questions. Et le champ de pays rend son drapeau dans la vue lire, en correspondance avec le cueilleur qui l'a produit. Vérifié: essai npm (14 gardes et 5 121 essais, dont 70 sur app/lib/memberProfile), tsc --noEmit, prochaine construction.
· kamo-internal
Reconstruire mon profil en héros et cinq pièces
:: Avoir un élément de 1 999 lignes de rendu treize cartes identiques en bas d'une seule colonne. Une aide à la sectionCard a donné tous les mêmes rayons, la même ombre, la même puce d'icône et la même ombre Même édition / Enregistrer / Annuler trio, donc "Informationscomptes" - deux dates Personne peut éditer - transporter exactement le poids de "Password - MFA". La mise en page était dire la vérité sur une hiérarchie que la page n'avait pas. La reconstruction : Un héros qui garde la résolution du papier peint de MemberHeader mot pour mot, cicatrice y compris, et ajoute l'identité qu'il ne faisait que décorer: name comme un seul morceau de grand type de la page, l'heure locale du membre tic-tac dans la zone THE, l'état MFA, le dernier signe, et un anneau de résistance. :: Cinq pièces derrière un rail - Identité, apparence, travail, accès, région - un ouvert à la fois, porté dans l'URL en tant que chambre. Une pièce dont toutes les La carte est fermée pour le spectateur ne rend aucun objet rail. Des champs de clic pour éditer et une barre de sauvegarde au niveau de la pièce, en remplacement de 39 boutons. Sauver ventilateur par fin d'évaluation sous le format allSlayled: un groupe qui réussit s'engage alors qu'un groupe qui échoue garde ses champs sales avec une raison. Cmd-K sur tous les champs, de sorte que les pièces cachent des choses sans les cacher. Squelettes stupéfiants en forme de carte au lieu d'une compresse à onglet complet. Deux défauts trouvés en lecture, fixés ici: L'adresse n'a jamais fonctionné dans le sens de l'EITHER. Le chargeur codait en dur cinq des chaînes vides et ne jamais lire de données.address, ce que SecurityService fait l'envoi; et la rue du client, ville, État, zip, pays n'est pas la Le texte est une adresse Emb Adress of ' address, addressDetails, localité, subdivision, code postal, pays. Donc il a été rendu en blanc pour Tout le monde et a sauvé les clés que l'entité ne porte pas. Maintenant utilise la forme le reste de la plate-forme envoie déjà, avec des essais aller-retour. "Nom juridique:" et "Born " étaient littéraux anglais dans MemberHeader, et le les étiquettes de lieu de travail et de statut de l'emploi étaient littérales en anglais composante. Tout est cloué. Structure. Les règles sont passées à app/lib/memberConfile, où c'est en réalité. les collectes - app/settings/- n'est pas dans l'liste butimatrice, donc un test écrit à côté de la page aurait été passé par ever running. field.ts is la clé de voûte: chaque champ déclaré une fois avec sa chambre, sa carte, son étiquette, sa porte et terminal. La palette, l'anneau de force, le ventilateur de sauvegarde et le port de droits Tous l'ont lu au lieu de le réimplémenter, et 57 tests épinglez les portes vers le bas. y compris qu'aucun champ n'est jamais plus visible que sa carte, et que l'édition n'est jamais plus large que de voir. Quick Tips est supprimé pour cet onglet uniquement, en omettant helpTips; ParamètresView rend le rail à partir de la languette active, de sorte que les neuf autres gardent le leur. Impersonner les mouvements depuis l'en-tête des réglages dans le héros. Supprime également ProfileTab.tsx (2 650 lignes), LoginSecurityTab.tsx (787) et MembershipPermissionsTab.tsx (2 136), qui n'avait pas d'importateurs. Les clés du dictionnaire ont d'abord atterri en kamo-traduction-dictionary 4bb91245. Vérifié: test npm (14 gardes et 5 106 tests), tsc -noEmit, next build, et check-i18n-keys --exigez-les-messages contre un nouveau clone du dictionnaire.
· kamo-internal
Un terminal Linux réel dans une fenêtre d'outil, et un sous-menu pour l'atteindre
L'option Linux Desktop nav devient un menu au lieu d'un lancement et d'un bureau à distance avec ses tailles, le terminal distant, exactement comme le softphone possède l'appel, la messagerie vocale et le texte. Un changement de registre le fait: «l'action» devient la suivante: «l'outil», et NavToolButton procède déjà à un sous-menu dans les trois placements. toolSections est déjà la source partagée pour la navigation et le bloc-bail d'origine, de sorte que les deux ne peuvent pas dériver. LE TERMINAL. xterm.js contre un vrai PTY sur la machine de développement du membre, donc il est un terminal et non un lanceur de commande: alt-screen apps (vim, htop, moins), 24 bits couleur, rapport de souris, pâte entre crochets, large et combinant les glyphes, cliquables Liens OSC 8. Rien n'est interprété sur le chemin et les touches sont des octets à la PTY et la sortie est arrière d'octets - ce qui est la seule façon pour un terminal en fait compatible avec ce que les gens courent en une. En plus de l'émulateur: un statut puce qui pulse plutôt que de compter sur la couleur seule, un titre qui suit le la séquence OSC propre shell de sorte qu'il suit cd et la commande en cours, copie-on-select avec Ctrl-Shift-C/V, Ctrl-Shift-F recherche, Ctrl -/-/0 zoom, et une palette qui suit le thème du téléspectateur. La coquille survit la fenêtre. Il fonctionne sous tmux clave sur la fenêtre id, donc a rafraîchir, connexion abandonnée ou une fenêtre-feuille restaur-retour à la même session avec son rollback et sa commande en cours - c'est aussi pourquoi un Lâchée se reconnecte avec le backoff au lieu de signaler une défaillance. Le le transport vit dans - free of React et de xterm, donc le backoff et la trame divisée sont testables sans DOM. LA TAILLE DE DESKTOP COURRISE EST GONE, et avec elle DesktopRésolutionPicker. Il a été fixé sur un paramétrage page quatre écrans à partir de chaque lancement et lire de localStorage, Alors "pourquoi est-ce qu'il a ouvert petit?" n'avait pas de réponse quelque part près de la chose qui s'ouvrait petit. La taille est maintenant choisie dans le même clic qui ouvre le bureau; openKamoDesktop le prend explicitement et un appelant sans avis passe «fit», C'est ce que la valeur par défaut a toujours été. Trois défauts trouvés et fixés en auto-révision, tous silencieux: le gestionnaire de raccourci a été fixé par un effet que les incendies avant l'émulateur async existent, de sorte qu'il Jamais lié du tout; fermeture d'une fenêtre pendant que sa demande de billet était en vol a ouvert encore une douille par la suite, laissant une coquille attachée à rien que le Un cap par membre a été compté; et les décorations de recherche ont été omises. Les deux couleurs de règle d'ensemble REQUISE D'ISEarchOptions. Taper les xterm refs au lieu de "any" est ce qui a attrapé le dernier. 405 fichiers de test / 5049 test passe, les 14 gardes sont propres, tsc est propre, et le la construction de la production réelle réussit - un tsc vert seul ne prouve rien ici. Dictionnaire poussé en premier (115c267f); vérifié par rapport à un nouveau clone la façon dont IC le fait, puisque les messages locaux/ sont gitignores.
· kamo-internal
Un quatrième état de fenêtre - flottement, traînée pour se détacher, faire glisser pour réorganiser
Une fenêtre d'outil pop-up a trois états: amarré dans la rangée le long de la le bas, maximisé sur la fenêtre d'affichage, ou minimisé à une tête de discussion. C'est ce que ajoute FLOATING - détaché de la rangée, tombé n'importe où sur l'écran, et redimensionnés à partir de n'importe quel bord - et l'atteint de deux façons. LE BOUTON. Un contrôle dans la barre de titre, portant la même icône que Détache une note, soulève la fenêtre de la fente dans laquelle elle était et cascade-t-elle à l'abri du quai afin que l'œil puisse le suivre. Pressé à nouveau, il revient à la querelle. Une fenêtre maximisée est non-maximisée et centrée à la place, puisqu'elle Il n'y a pas de fente à décoller. La RDA, qui est la moitié intéressante. Appuyez sur la barre du titre et Tirer est UNE geste avec trois résultats, et où la fenêtre est laissée go décider lequel: - libéré avec son bord inférieur à 96px du fond de la fenêtre d'affichage, il prend une fente dans la rangée - donc en traînant une vitre amarrée latéralement latéralement REORDONNE le quai, ce qui n'était pas possible auparavant du tout; - libéré n'importe où ailleurs il flotte là, qui pour une fenêtre amarrée est le moment où il se détache. Il détache exactement où il était, donc rien ne saute; - et une fenêtre flottante glisser vers le bas s'enclenche dans la rangée comme elle approche, à sa taille normale et en ordre avec ses voisins. Le EDGE inférieur est mesuré, pas le pointeur: faire glisser une fenêtre de 650px par sa barre de titre place le pointeur 600px au-dessus du quai sur le premier cadre, et un test de pointeur détacherait toute tentative de réorganisation. Rien n'est commis tant que le pointeur n'aura pas été adopté. La fenêtre transportée, la les voisins se balancinant pour faire de la place (ou des rangs de fer laminés derrière elle), la goutte le pont éclairant comme le quai approche et le halo autour de la fente il va terres dans toutes sont un aperçu résolu à partir de la boîte en direct chaque cadre - qui C'est ce qui fait échappé, et changer votre esprit à mi-chemin, rien coûter. Deux décisions plus petites qui valent la peine d'être nommées. Des fenêtres à quai sont maintenant positionnées de leur bord TOP plutôt que de poncer "bottom: 0"; en haut et en bas sont des propriétés différentes et aucune transition n'entraîne un élément entre donc le claquement aurait sauté quand il était chronométré. Et "resizable: false" devient un ÉLÉCHEL D'UNE VOIE une fois qu'une fenêtre est hors de la rangée plutôt qu'un veto - le compositeur de courrier électronique est l'un des outils de taille fixe, et il Est-ce que les parties à la fenêtre veulent le plus de place pour. L'ordre des rangées et la géométrie du flotteur survivent tous deux à un rechargement: l'instantané porte la boîte à flotteurs, la taille du dock à revenir, et l'ordre de la matrice, qui est le propre arrangement de gauche à droite du membre. Nécessite à la zkmo/tool-core 0.1.6 (setFloatGeometry / setFloatGeometry / setWindowOrder), heurté ici.
· SecurityService
Servir un terminal distant - un véritable shell sur une prise WebSocket
P passe un navigateur à un PTY sur la machine de développement du membre. Les trames binaires sont le terminal, les trames de texte sont contrôlées; à l'arrière-plan, un HTTP 101 sur un Un flux préfixé de longueur atteint l'agent sur le port déjà la politique du réseau permet, donc aucune modification du cilium n'est nécessaire. Le premier WebSocket dans ce service, et délibérément un logiciel brut. STOMP est un courtier de message sur un socket et ce qui voyage ici est un flux d'octets entre un un navigateur et un shell - une enveloppe autour de chaque frappe n'achète rien. L'AUTORISATION S'est contentée de savoir si le cœur. Un navigateur ne peut pas mettre un en-tête sur un Le constructeur de WebSocket, plutôt que d'enseigner la poignée de main à l'analyse, un le critère d'évaluation authentifié ordinaire prend la décision entière avec la session en main et tends la main vers l'avant comme un billet à usage unique qui est sans valeur 30 secondes plus tard et encore après une utilisation. Cela reflète le lien KamoDesktop, qui était durci pour cette raison exactement: un jeton rejouable se trouve dans l'histoire et dans Ctrl-Shift-T, et un shell est pire à cet égard qu'un bureau, pas mieux. La poignée de main ne lit rien d'autre du client - pas un nom d'utilisateur, pas un Comptez, seulement une taille écoute l'agent pince de toute façon. Le compte Linux provient de WhatsFor(le propre membre de l'appelant) id), donc une demande ne peut pas nommer quelqu'un l'autre coquille, et l'Origine est épinglée à l'hôte qui s'adresse. Aucun mot de passe n'est lire du tout: l'agent est racine et tombe dans le compte, donc la réversible Les besoins du guacamole ne sont jamais abordés sur cette voie. Vérifié avant le fait, de manière synchrone, dans le même Log répond "qui s'est connecté d'où" - avec IP, geo-agent et utilisateur-agent, à HIGH sévérité. Une ligne qui n'apparaîtrait que sur le succès serait absente exactement des affaires C'est cette question. Huit bornes par membre, car chacune est un PTY et un thread sur un VM partagée qui a été prélevée par la pression de mémoire auparavant. Fermer la douille ne tue pas l'obus; l'agent le met sous tmux de sorte que rafraîchir ou une connexion abandonnée se rattache au travail en cours. 21 essais: à usage unique, expiration de part et d'autre de la frontière, silence de type «j'ête» le plafond par membre et ses jetons de libération non séquentiels, et le codec de trame y compris une livraison à un octet à un temps, une durée déclarée absurde, et la lecture la ligne d'état de la mise à niveau sans avaler le flux derrière elle.
· KlusterServices
Donnez à l'agent un critère de PTY pour le terminal distant
GET/pty améliore la connexion à "kamo-pty" et devient un obus: un PTY per Fenêtre de l'outil de navigation, 'su' - 'user' dans la nouvelle session -A', les cadres pompés dans les deux sens du gomme brut. A 101 plutôt qu'une prise de vue. L'appelant est SecurityService qui détient le porteur jeton, pas un navigateur, donc il n'y a aucune raison de faire défiler la RFC 6455 en ensachuant reste stdlib-only. Après la ligne d'état, il s'agit d'une longueur de zunt32 et de type uint8 la charge utile, et le filetage par connexion de ThreadingHTTPServer est exactement la forme ces besoins. tmux, pas une coquille nue, et c'est la raison pour laquelle il est ici. Un PTY brut meurt avec sa prise, donc une page rafraîchissante, un ordinateur portable fermé ou un wifi blip tuerait un rouler build et kamo-internal restaure les fenêtres d'outils sur la charge, donc un restauré Un terminal revenait en retenant un cadavre. "New-session -A" fait la première connexion et reconnecter la même commande. La sécurité suit la règle existante du fichier: le nom d'utilisateur arrive déjà résolu de la session du membre et est re-validé contre USERNAME-RE et liste réservée avant tout début de processus, les ids de session sont vérifiés car tmux lit en tant que syntaxe d'adresse, les tailles sont serrées parce qu'elles allouent un cadre tampon sur une machine partagée, et un compte désactivé est refusé même si Il fonctionnerait toujours pour elle. Aucun mot de passe n'est lu du tout - l'agent est root et chutes sur le compte, donc contrairement au chemin Guacamole, le certificat stocké ne jamais quitte la base de données. TERM est forcé à traverser le zenvc parce que 'su'-' '-'-'re-repargne l'environnement à partir de rayer, et un terminal qui apparaît comme « dumb » n'a ni vim, htop ni moins. Les sessions de tmux abandonnées sont élaguées lorsque ce membre se connecte ensuite, ce qui a besoin ni une minuterie ni une liste de tous les comptes sur la machine. 24 essais: forme argv, refus réservé/invalide, serrage de taille, codec de cadre y compris un cadre divisé en deux lectures et une longueur déclarée absurde, contrôle la manipulation de la trame, et les quatre cas de la moissonneuse. 107 laissez-passer.
· kamo-shared-library
Enregistrer un terminal dev-machine dans le journal d'accès
Un membre qui ouvre un shell sur le bureau-1 a maintenant un type d'événement qui lui est propre. Que machine détient un cluster-admin kubeconfig et ses comptes ont un mot de passe sans mot de passe la gestion des paquets, qui est équivalente à la racine - "qui avait un œil là-bas, à partir de qui s'adresse, et quand, ", doit être responsable à partir du même journal d'accès qui Il y répond déjà pour les connexions. Sûr pour appendicer: system-access-logs n'entraîne pas de contrainte VÉRIFICATION (vérifiée en la production aujourd'hui) et le type d'événement est varchar(30). Contrat PhiResourceType, dont la liste blanche de la valeur Hibernate-emitted ddl-auto: update ne s'élargit jamais.
· SecurityService
Envoyer l'entreprise à côté du contact chaque fois qu'un enregistrement est étiqueté
Un enregistrement qui est à la fois une organisation et une personne s'appelle "Harmony Home Loans (Nickolas McGarry)" - la société dirige, le contact est éligible. Cette règle vit dans l'entité du navigateurLabel(), donc ces points d'extrémité cessent de choisir la moitié et d'envoyer les deux. - La chronologie de la grille/leads estampillée chaque entrée avec le contact et est revenue à l'entreprise. Par conséquent, la même façon de lire comme une personne sur sa chronologie et comme une l'entreprise sur le réseau qui l'a produit. - L'historique du crédit/de la cession principal n'a résolu le contact que. Résolu ici plutôt que dans le service de l'histoire partagée parce que c'est son seul moteur de rendu, et on trouve AllById sur les sondes distinctes de la page est une seule requête. - L'onglet Leads d'un compte envoyait zuid, organisationId et rien d'autre, donc chaque colonne est lue "---------------------------------------------- Il est maintenant envoie id (qui est ce sur quoi cette touche de table et les liens), les deux noms sont les moitiés, État et dateCréité. Le courrier électronique du chef de file est fermé à la manière dont le point de contact principal est partout ailleurs: votre propre chef de file toujours, n'importe qui n'est qu'avec VOIR-LEAD-CONTACT-INFO-OTÉRIERES.
· kamo-shared-library
Envoyer la société d'un compte à côté de son contact pour les sélecteurs de clients
Six sélecteurs de clients lisent AccountSummaryDTO et l'éditeur de commande, le service-job le formulaire, les détails de l'abonnement et le magicien, et l'onglet d'inscription du pipeline chacun d'entre eux a nommé un client par qui que ce soit le point de contact. Quelqu'un le choix du client auquel un emploi ou une commande appartient est à la recherche du client organisation. displayName est maintenant le contact UNIQUE. Il portait un suffixe "(-123)", qui avait un sens alors qu'il s'agissait de l'étiquette entière et des crochets imbriqués le moment venu La société l'a dirigé - "Harmony Home Loans (Nickolas McGarry (123)". L'uid est déjà un domaine qui lui est propre pour tout cueilleur qui doit séparer deux clients portant le même nom, et le navigateur compose les moitiés à travers une entitéLabel() que tous les autres écrans orientés vers le client passent également.
· kamo-internal
Communication View - l'ensemble du livre filtré en une seule chronologie
Trois modifications de/leads. La recherche rapide s'installe dans le héros, au-dessus des liens CRM Settings. Dans le filtre rangée c'était le dernier contrôle sur une ligne de onze déroulations, pouvant être trouvé seulement par balayer au-delà de tous. LeadManager est toujours propriétaire du voyage de la valeur dans le interrogation et dans le stockage de session qui restaure la barre de filtre sur le chemin du retour d'une tête - la boîte bougeait, rien d'autre ne l'a fait. Un interrupteur de basculement, centré dans la ligne de pagination: Lead View / Communication View. Deux positions nommées plutôt qu'une commutatrice, parce qu'aucune de celles-ci n'est "off" ce sont deux façons d'envisager le même ensemble filtré, et un nom de contrôle seulement l'un laisserait le lecteur deviner ce que fait l'autre position. Communication View remplace la grille par le même calendrier. Tirage de l'onglet de communication - même composante, les six sous-bobulaires, la même rubrique les rendus et lunaires à la barre de lecture de l'ensemble de la barre de filtre qui correspond actuellement. Chaque entrée porte une puce nommant son plomb et se liant dans celle-ci: cross-lead, une rangée qui le fait ne pas dire dont l'appel était il était illisible, et trouver la seule conversation valant la peine L'ouverture est la raison pour laquelle la liste numériser. Pas de compositeur de note, délibérément: a note doit être à peu près une avance, et une boîte qui ne pourrait pas dire qui est un piège plutôt qu'une commodité. Détails qui sont porteurs plutôt que liés: - La page de la grille est SUSPENDE dans la communication View. GET /api/security/leads écrit une ligne d'accès PHI par plomb, il retourne, et recherche une page pour rendre un écran montrant qu'aucun d'entre eux ne serait mis en l'état dans l'audit Traînée que personne n'a joué. - La chaîne de filtres remise à la chronologie est déboutée sur le retard de la grille. La grille déboutelle sa demande; le calendrier ne peut pas - il réinitialise chaque fois que le Changements de chaîne et incendies deux demandes par changement, donc la frappe "chaque" était de dix Les allers-retours, chacun écrivant un enregistrement de recherche PHI, aucun d'entre eux n'a avorté. - page/taille/tri sont déshabillées. la taille centrellement activement en collision, parce que la La chronologie fixe les siennes. - Les deux pistes du pager restent MOUNTED quand ils se vident. Un écran: aucun enfant n'est pas du tout un élément de grille, de sorte qu'ils auraient laissé l'interrupteur comme premier et le glisser dans la piste gauche, hors centre.
· kamo-internal
Ajouter JustCall en tant que type de serveur téléphonique
Ajout JustCall au cueilleur à - avec son API clé et secret, un basculement d'importation de contacts, un statut de justificatif sur les fournisseurs onglet et le logo. La partie intéressante est la numérotation. JustCall ne publie pas d'officier de l'état civil SIP et non Profession WebRTC aux applications tierces, et son seul appel sortant Le point d'extrémité pilote un agent vocal de l'IA plutôt qu'une personne - donc les rapports backend voixCliquez fausse, qui utilisent Softphone déjà les portes de l'enregistrement, et non Un téléphone portable est construit. Mais un membre de JustCall peut parfaitement appeler, pas ici, et "appels à la voix non disponibles avec le fournisseur actuel" serait un lie. dial() aiguille donc le numéro au dialler de JustCall. Ce transfert est son propre module plutôt qu'une branche à l'intérieur du crochet: c'est un lib concern, et le dire là le rend testable. Il utilise le web dialler plutôt que le justecall: le protocole de l'application de bureau s'enregistre, parce qu'un navigateur ne peut pas dire si cette application est installée et si un protocole n'est pas géré Ne fait rien du tout - un membre sans l'application cliquerait sur le cadran et regarderait Il ne se passe rien. Fournisseurs Capacités acquisesType de type afin qu'une fausse voix puisse être prise en compte plutôt que simplement être signalé: pour la plupart des fournisseurs, cela signifie "pas de numérotation", pour cela l'un signifie "cadré là-bas". Miroirs SipCredentialsResult.provider, qui existe pour la même raison. Le nouveau test de couverture est le double frontal de PbxProviderBillingCoverageTest un fournisseur dont personne ne se souvien d'étiqueter n'échoue pas fort, il rend comme un une carte vierge dans un écran qu'un administrateur utilise pour le choisir. Vérifié: tsc clean, les 14 gardes, y compris les clés de contrôle-i18n --request-messages, 4 938 essais virulents. "next build" n'a pas été contre ces changements: un autre Cette session a tenu ce répertoire de travail avec ses propres constructions simultanées.
· SecurityService
Une chronologie de communication sur l'ensemble /leads filtre, pas une seule piste
GET et prend la même chaîne de requête GET la page de détail de plomb tire - sur chaque plomb, la barre de filtre correspond. "Qu'est-ce qui a a été dit aux pistes que je travaille" est une question sur un ensemble, et jusqu'à présent la seule façon de le demander était de les ouvrir un à la fois. La traduction du filtre passe à LeadGridFilters de sorte que les deux critères d'évaluation résolvent un chaîne d'interrogation identique; une seconde copie dériverait, et la façon dont elle dérive est un la chronologie couvrant différentes pistes de la grille qui l'a produit. Deux bornes différentes, pour deux raisons différentes. Appels, messages vocaux, textes et Les courriers électroniques ne sont pas liés : LEAD-COMMUNICATIONS transportent ORG-ID et indexés sur (ORG-ID, OCCURRED-AT), donc une requête de clé passe à la correspondance de l'ordonnance le plus récent et teste chaque ligne par rapport au prédicat de grille en tant que corrélation EXISTES - le même coût si sept aboutissent à sept aboutissants ou soixante-dix mille. Notes et le chat ne peut pas être: ils vivent dans MEDIA-OBJS, qui n'a pas d'org et pas de plomb, et le seul jointo-repos est LEADS.STREAM-GUID, qui n'est pas indexé. Ces deux-là résoudre les fils de correspondance en premier, plafonné à 1000, et la réponse dit quand il Câblé plutôt que discrètement la chute de l'histoire. L'autorisation est la chronologie principale, appliquée en langage SQL. Une entrée porte une avance le contenu de son numéro ou de l'adresse plus de message, de sorte que LeadCommsReadGate indique maintenant aussi sa règle sur les trois formes qu'un lead peut avoir et émet le prédicat d'appariement. L'écrire une deuxième fois, c'est là que le bogue était : la première version était la suivante : a besoin de VISUER - UNASSIGNED-LEADS" et n'a pas respecté ce refus() tombe par rapport à ce contrôle à l'info-client, qui aurait mis en place la correspondance de chaque chef de file groupé devant un membre qui n'a qu'à droite de la piscine. Les deux formes sont maintenant épinglées à les uns et les autres de manière exhaustive - chaque bonne combinaison contre chaque forme. Contrairement à un compte, cela ne s'effondre PAS un événement qui a atteint deux des pistes appariées. Deux raisons pointant de la même manière: chaque ligne nomme la tête appartient à et "ce que l'appel atteint tous les deux" est un fait sur le livre en cours d'exécution. et l'effondrement des rangées sur une seule page fixe peut laisser le survivant en dernier twin qu'une nouvelle entrée ne peut pas faire double emploi. Les requêtes de critères sont tirées dans LeadGridCommsQueries en tant que fonctions pures. LeadGridCommunicationsSqlTest peut les rendre contre les métadonnées Hibernate réelles. Cela compte ici plus que d'habitude: la propre spécification de la grille émet déjà EXISTS sub-requis, et cela l'emboîte à l'intérieur d'un autre - qui est exactement où Le Hibernate 6.2.13 de ce service et le 6.5 de la bibliothèque partagée diffèrent.
· VOIPService
Wire JustCall in via l'abstraction du fournisseur de téléphone
JustCall (api.justcall.io/v2.1) en tant que PhoneProvider complet: historique des appels, textes, messagerie vocale, enregistrements, répertoire des agents et disponibilité, plus signé des enregistrements webhooks et une importation de contacts optionnels. L'authentification est l'un des comptes à l'échelle T-clé/croyèrelet envoyé comme valeur brute d'autorisation "clé:secret" - pas un porteur jeton, qui n'authentifie rien et retourne un 401 qui se lit comme un mauvais les titres de certification. Trois formes de l'API de JustCall sont le moteur de la conception: La messagerie vocale n'est pas une ressource. Il s'agit d'un appel dont le type call-info. "Voicemail", portant sa transcription en ligne et son son audio derrière celui-ci l'enregistrement du point d'arrivée comme n'importe quel autre appel - getVoicemails est donc getCallHistory avec un filtre, et il n'y a pas d'état de lecture pour marquer. Il n'y a pas de microvisance pour téléphone portable. JustCall ne publie pas d'officier de l'état civil et non Jeton WebRTC à des tiers, et son seul point d'extrémité à l'appel sortant est le moteur d'un AI Voice Agent plutôt qu'une personne. voixCalls est donc faux, ce qui est Quelle utilisation Softphone porte déjà l'enregistrement, et getSipCredentials refuse avec une explication au lieu d'un demi-enregistrement. Le répertoire est en lecture seule, et il n'y a pas de concept de dispositif, donc ceux-ci gardent l'interface lance par défaut plutôt que de faire semblant d'écrire. Les crochets Webhooks sont enregistrés par instance à l'adresse suivante: abonnement par type d'événement. Le HMAC-SHA256 de JustCall couvre l'URL enregistrée, de sorte que la chaîne d'interrogation se trouve à l'intérieur du matériel signé et ne peut pas être réécrit pour débarquer les événements d'une org sur le serveur téléphonique d'un autre. L'URL est enregistrée dans config.json à l'approvisionnement car la vérification doit signer la même chaîne JustCall l'a fait - la reconstruire à partir de la configuration commencerait à échouer silencieusement le au moment où l'URL de base a changé. Les textes entrants et les événements d'appel atteignent les chemins que RingCentral utilise déjà. Le manipulateur de VoipMessageService était en forme de RingCentral partout, donc son analyse est scindée de son ingest: les deux rails partagent maintenant le dedupe, l'interception par mot-clé, la conversation upsert et le lead link. Ce partage est délibéré - le mot clé c'est l'échelon qui enregistre une clause de non-participation, et un second rail cultivant sa propre copie de la séquence est comment on finit par ne pas honorer STOP. SmsKeyword Commutateur de réponse de SmsKeyword a gagné le nouveau rail pour la même raison: il s'agit d'un changement de déclaration, donc un Une constante non inscrite n'aurait répondu à personne. MMS est par URL publique uniquement - JustCall n'accepte pas les octets téléchargés - donc un fixation est garée derrière une URL non désagréable de courte durée sur ce service et ce lien est remis. Délibérément pas un URL présigné en magasin d'objets: MinIO Voici une URL présignée est signée pour l'hôte il nomme, et le fetcher de JustCall ne peut pas résoudre une adresse dans le centre-cluple il serait 404 pour eux tout en travaillant parfaitement de l'intérieur de l'amas. C'est ce que Le service est déjà accessible au public parce qu'il reçoit leurs pochettes web. L'importation de contact est désactivée à moins qu'elle ne soit activée: le carnet d'adresses du client est l'accès par membre contrôlé, et l'importer au moment où une clé est collée serait collée Soyez une surprise. Les contacts sont détenus via l'agent JustCall-id la synchronisation de l'extension déjà enregistré, et tous ceux dont les cartes d'agent n'ont pas de membre Kamo sont sautés plutôt que les garées quelque part partagées. Persistance va à EmailService, qui possède le les tables de contact. Le résumé de l'appel d'ACI, le sentiment et le score de JustCall sur le même appel lu et sont sur la surface de CallLogEntry. Non persistant : TÉLÉPHONE-LOG n'a pas de colonnes de ce type, le fournisseur les retourne sur chaque lecture, et l'ajout de colonnes coûterait une DDL fenêtre pour un duplicata de leur magasin. Pas de DDL dans ce changement.
· EmailService
Critère d'évaluation interne pour l'importation de contacts à partir d'un système externe
L'intégration JustCall de VOIPService doit décrocher les contacts d'un client dans le carnet d'adresses du membre de droite, et c'est là que les contacts sont écrits: un contact Carte uniquement scalaires, avec ses e-mails, téléphones, adresses, orges, URL, IM et les relations dans sept tableaux sans cascade, accessibles uniquement par ContactDetailStore. Un appelant écrivant ces tableaux d'un autre service serait supprimer silencieusement chaque numéro de téléphone - le champ d'une intégration téléphonique existe pour livra - donc la persistance reste ici et les postes de l'appelant. La propriété est la partie porteuse. CONTACT.OWNER-ID NON NON NON NONNE NULL et points à les utilisateurs, et un propriétaire de ContactBook est son contrôle d'accès (un livre sans propriétaire) n'appartient à personne et 404s pour tout le monde), de sorte qu'un lot doit désigner le membre de son Les contacts appartiennent à l'intégrité générale et ne leur sont pas refusés. Chaque source obtient son propre livre derrière une ligne ContactIntegration plutôt que d'être mélangé dans "My My Contacts": les lignes synchronisées et les rangées de type main ont des cycles de vie différents, et Un membre peut cacher ou laisser tomber les importés sans toucher les leurs. Les ups font correspondre sur uid, que l'appelant sert d'espace de noms à son système. L'UID est unique par livre, donc c'est aussi ce qui fait une nouvelle mise à jour au lieu d'une seconde copie de tout. Monté sous /api/interne, entier gardé par InternalAuthFilter - il n'y a pas session d'appartenance derrière ces appels, donc sans ce filtre ce serait un le point d'extrémité pour écrire des contacts arbitraires dans des livres de membres arbitraires.
· kamo-shared-library
Ajouter JUST-CALL en tant que type de fournisseur de téléphone
Applique à l'ordinal 5. est EnumType.ORDINAL et ne porte aucune contrainte CHECK, donc l'ajout est sûr et l'insertion n'importe où d'autre ordre de repointer silencieusement les lignes existantes sur un autre fournisseur PbxProviderBillingCoverageTest brosse l'ordre de l'autre côté. TROISIEME PERSONNEL: l'organisation est titulaire de son propre abonnement JustCall (leur L'API a besoin au moins d'un plan d'équipe) et JustCall porte les appels, donc c'est un la charge d'intégration, pas l'hébergement. PbxBillingClass.of n'a pas de bras par défaut, qui est ce qui a forcé la décision plutôt que de laisser un nouveau fournisseur ne facture rien pour toujours.
· kamo-internal
Une couleur de papier par bloc, et des blocs qui correspondent à leur texte
BLOCKS MAINTENANT LEUR CONTENU. Les blocs du lecteur étaient tous de 200px de haut, peu importe Ils détenaient, parce que richeTextExtension configure l'éditeur avec minHeight: 200px - la forme du compositeur de l'article, où l'éditeur est la page. Passage du lecteur à RichTextView l'enlever; rien dans la vitre ne serre un La hauteur du bloc maintenant, donc c'est exactement aussi grand que ses mots. LES éditeurs du COMPOSEUR CROISSANTE D'INSTAD DE SOLDE. Même 200px, plus débordement: auto sur le récipient, signifie que chaque bloc a ouvert trois lignes trop haut et se tend ensuite une barre de défilement plutôt que de croître - une barre de défilement à l'intérieur d'un bloquer à l'intérieur du scroller de la page. KbArticleEditor gagne "autoGrow": le le conteneur s'arrête de faire défiler, la zone d'écriture commence à la hauteur d'une ligne, et les tailles de racines à contenu au lieu de remplir son hôte. Opt-in, donc l'article Compositeur conserve la forme qui convient à un document de la taille d'une page. COULEUR DE PAPIER. Chaque bloc porte un, choisi parmi NoteColorMenu, le même menu. et la même palette les notes et les vitres du pas de lanceur utilisent, donc un swatch signifie une chose sur le produit plutôt que trois. La couleur est stockée comme suit: ID de palette et résolu par la résolutionStickyColor à rendre, donc les deux Le compositeur et le Centre d'interaction peignent à partir d'une source et d'une palette ultérieure La correction atteint les scripts écrits aujourd'hui. Dans le lecteur, un bloc coloré conserve sa couleur, qu'il s'agisse ou non de la courant un. "Où suis-je" est déjà porté par la frontière, l'ascenseur et le épine; humilier le papier aussi faire ressembler le choix de l'auteur à un une faute de rendu.
· kamo-internal
Ajouter le logo du fournisseur JustCall
Le dossier logo VOIP avait FreePBX, Microsoft et RingCentral mais non. JustCall mark, donc n'importe quelle liste de surface JustCall en tant que fournisseur avait Rien à rendre.
· kamo-shared-library
Une couleur de papier par bloc
- tenant une ID de palette - "feu", "verre" et jamais une valeur hexagonale. Stocké la façon dont les notes et les vitres de lancement stockent les leurs, pour la raison que plutôt que pour la cohérence: la palette est définie une fois sur la client (STICKY-PALETTE) et chaque surface résout un id travers resolveStickyColor. L'hexe persçant allait congeler la teinte d'aujourd'hui dans la rangée, donc une correction ultérieure à la palette fixerait les notes et quitterait tranquillement le des scripts sur l'ancienne couleur et le même swatch signifieraient alors deux différents les choses en fonction de l'écran à partir duquel il a été choisi. Null n'est pas de couleur: le bloc porte la surface sur laquelle il repose. Un blanc ou la valeur de l'espace blanc est normalisée à nulle sur le chemin, parce que "" n'est pas "non Couleur de la couleur de la palette pour la résolutionStickyColor et il remet la première antenne de la palette, donc un auteur qui a blanchi la couleur aurait eu du citron. Porté à travers le bloc complet remplacer comme tous les autres champs, et couvert Là: la couleur survit à une édition, et une édiction effacée revient nulle.
· EmailService
Laissez un message envoyé porter des images à l'intérieur de son corps
Le corps avait quatre formes possibles et send() ne pouvait construire que trois. Le branche multipartie/liée - celle qui met une image où le cid du HTML: indique qu'il s'agit d'un point situé derrière la branche de la pièce jointe, donc un message avec les deux collés image et un fichier ont perdu l'image sur le chemin de la sortie: le corps a conservé un cid: référence à une partie qui n'est plus dans le message, et rien ne le dit. C'était aussi inatteignable dans la pratique, car seule la voie transactionnelle jamais fixée inlineImages; rien de ce qu'un membre envoyé ne pouvait y arriver du tout. applyBody construit maintenant la forme de l'appel de contenu pour - html seul, lorsque le corps fait référence à des images, mélangés lorsqu'il y a des attaches, emballage mixte liés à la fois - et une invitation à calendrier conserve ses images en offrant la solution à l'alternative HTML. répondez et passez à l'avance envoyer, donc ils hérie tout cela. /send prend les images comme leurs propres parties binaires, chacune nommée pour le contenu id le HTML fait déjà référence. Base64 à l'intérieur de la partie JSON coûterait à nouveau un tiers en taille contre le plus petit plafond de la chaîne, donc une capture d'écran ou deux être refusés pour une raison dont le membre ne pouvait rien faire. Le nom d'une partie devient a En-tête Content-ID, donc InlineImageParts le met en correspondance avec la forme exacte Compositeur Monte et refuse tout le reste - un mauvais pas l'envoi plutôt que de tomber tranquillement et de laisser un trou dans le corps.
· kamo-asterisk-support
Reconcilier les blocs WebRTC par extension au lieu d'éditer à la main un fichier
Une extension créée via l'API de FreePBX n'obtient aucun bloc WebRTC, donc il s'enregistre sur WSS et n'a alors ni DTLS ni ICE - le navigateur softphone affiche un un appel connecté ne transportant pas d'audio. Ces paramètres ne peuvent être exprimés nulle part FreePBX les acceptera: «dtls-cert-file-file-» et les transports ne sont pas des colonnes en la table "sip" et non les champs sur la mutation "AddExtension", de sorte qu'ils doivent: -" -" -'ext'(-)-(-)-(-)---------------------------- était un fichier Maintenu de la main dans une ConfigMap, ce qui signifie chaque nouvelle extension a été silencieusement brisée jusqu'à ce que quelqu'un se souvienne de l'éditer et de se relargérer (8888 sist non inscrits sur la liste pendant des mois). L'extension 8777 est la dernière en date. WebRTCReconciler lit la liste des extensions parmi les produits générés par FreePBX pjsip.endpoint.conf et maintient une section gérée délimitée par marqueur en étapes avec , toutes les 30. Les extensions supprimées perdent automatiquement leur bloc pour une section qui n'existe plus fait de log d'astérisque "La section n'existe pas" sur chaque rechargement. Il ne comble que les lacunes: tout bloc écrit en dehors de nos marqueurs (les KlusterServices liste, un administrateur) se laisse exactement comme il est, n'est jamais dupliqué et jamais pris en charge. Seuls les critères d'évaluation entièrement numériques sont touchés, de sorte que les troncs ne sont pas épinglés à a WS transport avec DTLS forcé. Un pjsip.endpoint.conf manquant est un no-op plutôt que "extensions nulles", qui autrement enlèverraient WebRTC de chaque extension qui en a une. OFF par défaut (MANAGE-WEBRTC-ENDPOINTS), sur pour k1m1. Le bloc est exactement incorrect pour un téléphone de bureau SIP: il force DTLS-SRTP que le téléphone ne peut pas faire et le pince à un transport qu'il ne parle pas. Deux choses mesurées sur la case vive k1m1 plutôt que supposées: - Le rechargement doit être le module reload res-pjsip.so, pas le 'pjsip reload'. Après l'ajout d'un bloc de '[8999'(-)', 'pjsip reload', 'pjsip reload', 'pjsip reload', 'pjsip reload', 'pjsip reload', 'p un module rechargement l'a appliqué, et un module rechargement l'a également retourné lorsque le module le bloc a été enlevé. En utilisant le propre «pjsip reload» ici, il serait écrit un corriger le fichier et laisser la configuration en cours mal. - Un bloc (-) ne peut que résoudre les options ADD, ne jamais l'emporter. S'ajouter à un critère d'évaluation dont la configuration générée audit Il a laissé sur le 'no' 'no' de la première valeur gagne. (-webrtc-yes-yes-yes-yes-yes-yes-yes-yes-yes-yes-yes-yes-yes-yes uniquement parce qu'il s'agit d'un abréviation additif, et non d'un champ stocké.) Tout ce qui doit CANE une valeur générée doit être fixé dans le FreePBX base de données. Vérifié par rapport au réel /etc/asterisk: correctement choisi celui l'extension découverte à partir de 23, a sauté le tronc Erik-Primary, a laissé l'existant L'octet pour l'octet est identique, et était un non-op sur la deuxième passe.
· kamo-internal
Impersonrpersonner, de sorte qu'un opérateur peut ouvrir un orge en tant que membre
Montré à côté de Entrée sur chaque vue /réseau pour un administrateur de plate-forme le nouveau droit IMPERSONATE. Un droit différent de SYSTEM-USER et délibérément non impliquée par celui-ci: entrer en tant qu'utilisateur du système est une identité visible et séparée a locataires peuvent voir dans leur propre liste de membres, alors que cela ne produit aucune session en aval peut le constater à partir de cette personne qui se connecte en elle-même. Le sélecteur est MemberPickerDialog et le même pop-up le filtre /leads Agent ouvre - inchangé. Il possède déjà la recherche, la paging, la manipulation du clavier et la façon dont une ligne inpossable s'explique. Ce qui est nouveau, c'est son «fetcher», qui remplace le point d'extrémité du répertoire et les points de l'organisation cible membres, parce que le répertoire par défaut est l'ensemble de la session et c'est C'est précisément la mauvaise liste. Personne n'est filtré côté client. Le serveur marque un compte dieu, une plate-forme administrateur ou un membre hors-bord non-sélectionnable avec une raison, et la table de raison de dialogue a grandi pour les couvrir: cacher ces rangées laisserait un opérateur à la recherche d'un collègue clairement dans l'organisation et obtenir Rien de ce qui est en retour, qui se lit comme une recherche interrompue plutôt que comme un refus. L'onglet est revendiqué de manière synchrone à l'intérieur du propre clic du cueilleur, avant le attendre, et sa sessionStorage blanc - le même manche de danseEnter documents, pour les deux mêmes raisons: un pop-up ouvert après une attente est un par le navigateur jamais voir n'importe qui demander, et une fenêtre de même origine. id inclus. Élimine également l'icône que l'onglet de l'administration de la plate-forme a besoin pour la nouvelle droite; tsc attrape C'est à cela qu'est à cela qu'est le RIGHT-ICON comme un compte rendu exhaustif.
· SecurityService
Entrer une organisation locataire en tant que membre, à partir de / réseau
Une deuxième porte à côté du mode dieu du même or. Relâché sur le nouveau IMPERSONATE Plateforme droit via «RequirePlatformRight», où la porte existante est fermée la session portant GD. Conservé comme deux maîtres plutôt qu'un avec un drapeau. Leurs portes d'appel sont VivePlatformRight n'a pas de variante manuelle de Une porte que vous devez vous rappeler d'appeler est une porte qui finit par obtenir oubliés sur le point d'extrémité qui était en fonction. Qui peut être ENTRE ENTRE CHAQUE est une question distincte, et ImpersonationTargetRules répond à sa fonction pure par rapport aux faits résolus: refusés pour le haut niveau org, vous-même, une adhésion sans utilisateur, l'utilisateur du système, un compte dieu, un administrateur de plate-forme, ou toute personne qui ne pouvait pas se lier en soi. Il en est de même la fonction décide si une ligne dans le cueilleur est sélectionnable, de sorte que la liste ne peut pas offrir à quelqu'un le point d'extrémité qui se détournerait. La porte de la même version ne partage délibérément PAS ces règles. Il opère à l'intérieur l'organisation de l'appelant, qui pour un dieu admin est généralement le niveau supérieur l'une, et sur les personnes qui sont souvent des administrateurs eux-mêmes - les deux les refus ici. Le pliage des deux ensemble casserait la page des paramètres ou Élargir discrètement celui-ci. - remplit le cueilleur. C'est le seul critère d'évaluation dans que le contrôleur nommant une organisation autre que celle de la session, c'est pourquoi il est un gestionnaire séparé plutôt qu'un paramètre sur /rearche: la promesse de la classe que la recherche ne peut pas être élargie par accident reste vrai. Les personnes refusées restent dans la liste avec une raison plutôt que de disparaître d'une recherche pour un collègue qui est clairement dans l'orge. workspaceHostFor se déplace hors d'EnterAsController dans WorkspaceHostResolver, depuis les deux portes ont besoin d'une réponse identique. Deux copies de "l'hôte est ouvert" est comment on continue d'envoyer les opérateurs à un certificat interstitiel après l'autre s'arrête. Ses tests se sont déplacés avec lui.
· kamo-shared-library
IMPERSONATE, de sorte qu'un opérateur peut entrer dans un locataire en tant que membre
Applique à PlatformRightType plutôt qu' insérée: getSortOrder() retours ordinal(), donc un droit ajouté au milieu redonne tous les droits en dessous dans le console. Les subventions sont «supplémentées (STRING), donc l'ajout de changements n'a pas déjà changé accordée. Délibérément non replié en SYSTEM-USER. Ce droit entre en jeu comme un visible, une identité distincte qu'un locataire peut voir dans sa propre liste de membres et une piste d'audit; Celui-ci produit une session que rien en aval ne peut dire de la signature du membre en soi. Différentes questions, un rayon de souffle différent, donc un opérateur Le droit d'avoir droit à la première n'a donc pas droit à la seconde. SignalVisabilityTest MANAGE-REPORTS épinglé comme la valeur LAST, qui s'ajoute brise en ne prouvant rien - l'invariant qui compte, c'est que rien n'était ABOVA LE MARQUE, donc il épingle maintenant l'ordinal à la place. Deux recherches de dépôt par lots pour le cueilleur derrière: les membres un ensemble de les utilisateurs sont hébergés dans une organisation, et lequel d'un ensemble de membres sont plates-formes les administrateurs. Rang-at-a-time c'est-à-dire deux requêtes par nom, sur un contrôle qui re-sondu à chaque frappe.

Votre univers vous attend.
Commencez gratuitement en quelques minutes. Ajoutez des produits quand vous êtes prêt. Pas de migration, pas de nouvelles connexions.
Gratuit pour toujours — aucune carte de crédit requise