Changelog
Cosa c'è di nuovo.
Ogni miglioramento alla piattaforma, come si spedisce.
· kamo-internal
Percorsi proxy di esecuzione dei membri e il modello wizard puro
Otto percorsi 1:1: /api/docs/legal/member/** attraverso forwardToApi (PATH ONLY — forwardToApi possiede la stringa di query) e /api/esig/member/** direttamente a ESIG SERVICE URL con generateOTK, perché APIService inoltra /api/docs/** e niente avanti /api/esig/**. One OTK, una richiesta a monte per percorso: OTKAuthFilter ottieneAndDelete. I percorsi PDF trasmettono e conservano lo stato a monte, quindi un 409 (il contenuto congelato digerire non corrisponde più ai byte memorizzati) raggiunge la procedura guidata come un 409 piuttosto che come un PDF corrotto. Il consenso è l'unico percorso che non deve parse il suo corpo di successo: ESigService lo risponde con un vuoto 200. Ogni regola guidata vive in un modulo puro perché vitest qui raccoglie solo .test.ts nell'ambiente nodo. Un documento firmabile viene visualizzato dal segno percorso — questi sono i bytes ESigService flattens, e quello che vedete deve essere quello si firma; un documento di riconoscimento-solo rende da DocsService versione-pinned Percorso. L'asse passo è ordineIndex ordine e la fase di attestazione esiste anche per un pacchetto con zero documenti da firmare.
· kamo-internal
Portare il core firma kamo-signer in kamo-internal
Ogni pacchetto @kamo/* è privato: vero con le esportazioni: "/src/index.ts" e nessuna costruzione passo, quindi non c'è artefatto pubblicabile — i file vengono copiati e rewired su importazioni relative. Il comportamento è invariato; solo le importazioni e i18n movimento. pdfjs-dist 4.10.38 con un lavoratore SELF-HOSTED copiato da un passo prebuild. No. pdf.js 4.4.168 da cdnjs, che è un motore diverso e inaccettabile per una superficie giuridicamente vincolante, e i due Gli oggetti GlobalWorkerOptions rimangono non corrotti solo perché le istanze del modulo Non ci vediamo mai. Non FieldElement.tsx: i rendering FieldControl pointerEvents:'none's previews with no value binding — un'anteprima progettista, non un ingresso. useTranslations esce dai quattro componenti di firma: chiamano kamo-signer proprie chiavi di messaggio, il dizionario di kamo-internal non li ha, e nuove chiavi non può essere inventato. Gli archi arrivano come prop. SIGNATURE FONTS è un oggetto troppo piuttosto di quattro carichi successivi/font/google per una modalità; il carattere digitato id cavalca ancora attraverso CapturedSignature.typedFont così flatten e il certificato non sono interessati. Due deviazioni marcate da una copia verbatim, entrambi in signStore: - necessario-ness ora skips leggereOnly campi. kamo-signer li contava; ESigService's FieldCompletion — l'applicazione del lato server spedito — non ("se (f == null | f.readOnly() ||| !f.required() continuare;"). Mantenere il copia firmatrice più rigorosa del server parcheggierebbe un membro su un gap che non hanno controllo da chiudere mentre il server considera la busta completa. - bozza di guardie di persistenza localeStorage invece di finestra. la finestra è sbagliata domanda: localStorage può essere assente (configurazione server) o gettare l'accesso (modalità privata, archiviazione divisoria), e una bozza non deve mai prendere la procedura guidata con esso.
· DocsService
Montare la superficie del membro a /api/docs/legal/member/**
Un controller separato con un imbuto separato, perché l'autorizzazione qui è identità e non un diritto HR. Routing questi attraverso sorvegliati() significherebbe bloccare ogni dipendente dalle proprie scartoffie o allargare LegalPackageAccess fino a quando la griglia dei modelli e il roster dell'anteprima del pubblico sono aperti all'intero org; la classe non tiene un riferimento a LegalPackageAccesso così il collegamento non è disponibile. Nessuna mappatura prende un id membro o un org id — entrambi provengono dalla sessione. Servizio ResponseStatusExceptions mantenere il loro stato: 404 non-yours, 409 già finito, 422 non riconosciuto e 503 esign-non disponibile sono quattro istruzioni diverse, e uno di loro significa che il membro già è riuscito. Un'eccezione inaspettata è fisso-stringa 500: eco e.getMessage() è tollerabile sulla superficie HR, ma questo uno ogni dipendente può raggiungere. Estrazione di KToken spostato alla sicurezza/SessionKToken in modo che questo non è il suo terzo copia verbatim.
· DocsService
Pacchetto attestazione sul traguardo, e la divisione EXECUTED/AWAITING Altri
Scrive il WORM LegalPackageAttestation: attestazioneTextSha256 dal FROZEN versione (il progetto di formulazione del pacchetto è mutabile e potrebbe già essere stato reworded), manifestSha256 sopra il ordinato [{documentUid, contentSha256, ordinareIndex}] effettivamente presentato, attestatoA set di applicazioni, sorgenteIp da un destra a sinistra X-Forwarded-Per passeggiata, provaBlob verbatim in modo che il digest può essere più tardi. Il cliente non si fida per il completamento. Prima che tutto sia scritto, ciascuno la busta del documento firmabile è rilettura da ESigService; il mio destinatario deve essere SIGNED, e PARTIALLY SIGNED NON è crollato il modo in cui crolla, quindi una contro-firmatura in sospeso produce AWAITING OTHERS piuttosto che un pacchetto che sostiene di essere eseguito. Una lettura fallita rifiuta la finitura — una non e' una prova che qualcuno abbia firmato. Un pacchetto con zero documenti firmabili non crea busta, chiama ESigService non e l'attestazione è la sua unica prova di esecuzione. Un secondo traguardo restituisce la riga esistente: @PreUpdate dell'entità lancia per design e la L'indice UNIQUE della migrazione su assegna uid è il serializzatore reale.
· DocsService
Identity-authorized membro leggere la superficie per le assegnazioni
LegalAssignmentOwnership è una guardia SEPARATE da LegalPackageAccesso di proposito: un membro che esegue il proprio accordo non ha diritto alle risorse umane e ampliando le risorse umane letto set per ammetterli avrebbe consegnato ogni membro la griglia di modelli e la l'anteprima del pubblico è pieno roster con e-mail. Tutto quello che non è il chiamante il proprio incarico risponde a un identico 404 — un 403 confermerebbe l'id è reale. dettaglio() fa la prima visualizzazione di contabilità sulla riga HR (firstViewedAt, PENDING -> IN PROGRESS) piuttosto che in ESigService, in modo da la macchina è intatta e il distintivo rimane onesto. La parola di attestazione viene dalla versione FROZEN, mai dalla bozza mutabile del pacchetto. documento Pdf serve documenti ACKNOWLEDGE-ONLY e verifica il ImgDat servito content-address digest contro i contenuti congelatiSha256 prima che serva un byte; saveImgContent repoints img.setDat su ogni Docs salvare, così la deriva è live. I documenti firmabili sono rifiutati con un 409 che nomina il percorso di esign — quelle byte deve venire dal servizio che li appiattisce. KToken's orgID/memberID sono primitivi lunghi, quindi il piano è "= null" identità controllare è 0 invece; estrattoKToken lascia 0 indietro per un campo di sessione assente.
· DocsService
Forma canonica manifesto e IP client resistente allo spoof
manifestSha256 hash il ordinato [{documentUid, contentSha256, orderIndex}] membro è stato effettivamente mostrato, lunghezza prefisso in modo che un uid artigianale non può imitare un campo confine e fare due diversi set di documenti hash lo stesso. proofJson memorizzato verbatim e round-trip torna allo stesso digest — una prova blob che non può rigenerare il proprio hash non prova nulla. LegalClientIp cammina X-Forwarded-Per RIGHT-to-LEFT e prende il primo giro pubblico. DocumentAccessAuditor lo legge da sinistra a destra, che è controllato dal cliente; che il difetto preesistente non è fissato qui, ma non deve essere la fonte di un fonte probatoria Ip.
· ESigService
Superficie di firma del membro autorizzato a /api/esig/member/**
OTKAuthFilter bypassa solo /actuatore, /api/esig/pubblico e /api/esig/internal, così questo prefisso è dietro il personale OTK auth con orgId/memberId già sul richiesta. Il destinatario non è mai una variabile di percorso: viene risolto abbinando EsignEnvelopeRecipient.memberId al membro OTK id, quindi non esiste un parametro membro può cambiare per raggiungere la fila di un collega. Non-fondato, non-your-org e Non su questa pista tutti rispondono a un 404 identico. No /delegate — consegna un documento di conformità a un'e-mail esterna arbitraria senza approvazione e nessuna bandiera disabilitata; esclusa per omissione, non per bandiera. No. /decoder e no /stepup o: decoder-scoped del destinatario appartiene al vuoto delle risorse umane percorso, e passo-up è messo in chiave su una sessione di segnale Redis questa superficie non ha. signerIpAddress proviene da un RIGHT-to-LEFT X-Forwarded-Per una passeggiata. EsignPublicController.clientIp legge da sinistra a destra, che è controllato dal cliente e quindi spoofable, e quel valore atterra su un campo di prova.
· kamo-internal
Pacchetti assegnati sub-tab e consegna/redeliver/void azioni
AG Grid Community su una fetch MUI-paginated — La Comunità non ha un modello di riga lato server, così le pagine del server e la griglia rende esattamente ciò che è stato consegnato. L'accusato colonna è derivato lato server dallo stesso stato che il chip rende, quindi i due non possono disaccordo, e un documento firmabile senza busta solleva un avvertimento piuttosto che sedersi per sempre. La colonna del filtro a destra è guidata dal termine membro del gruppo plurale dell'org, dal dati, con una riga standalone "All" — deliberatamente non uno interpolato "All {Team I membri}" stringa, perché l'unico tale messaggio nel dizionario ha un rotto segnaposto impostato in 12 di 22 locali e nuove chiavi non possono essere inventate qui. Il roster riutilizza il punto finale di anteprima del pubblico esistente piuttosto che scrivere un tredicesima copia dei membri-subscribers + team-members-appaltatori dual fetch, che restituisce i membri PROSPECT, CANDIDATE, TERMINATED e RESIGNED. Il paginatore "1-25 / 100" è costruito da dati piuttosto che da common.table.of, il cui il valore è un EMPTY STRING in pl.json — la guardia chiave prova solo una chiave esiste in en. Void utilizza una parola di sfida VOID fissa: cancella strumenti legali dal vivo og-wide.
· kamo-internal
Pacchetto legale consegna/redeliver/void proxy e client di assegnazione
Thin 1:1 forwardToApi percorsi — una richiesta a monte ciascuno, perché OTKAuthFilter fa getAndDelete e un loop per-membro in un prossimo percorso avrebbe bisogno di un OTK per membro. The elenco passa un PATH SOLO; forwardToApi fonde la stringa di query del browser stesso. La mappatura di stato-to-i18n è la vera guardia, non check-i18n-keys.mjs: quella sceneggiatura solo dimostra che esiste una chiave in en, e messaggi / è gitignored, quindi un passaggio chiave aggiunto localmente e poi fallisce la costruzione del Docker. Ogni chiave qui è stata verificata in tutte le 22 locali per presenza e uguaglianza segnaposto, e un perno di prova che nessuno dei quattro noti le chiavi danneggiate sono mai restituite. Una selezione vuoto vuoto non invia nessuna chiave di squadraMemberIds affatto — che l'assenza è ciò che seleziona il ramo org-wide; un array vuoto non avrebbe nulla vuoto e non riferire nulla. RedeliverResult NON estende DeliveryResult: RedeliverResultDto non ha versioneNumero E' solo che... Inheriting avrebbe dichiarato proprietà il backend non invia mai, quindi consegnareSummaryParts legge nuovoVersionNumber per un redelivery invece di segnalare v0.
· DocsService
Org-scoped, paged, pacchetto legale filtrabile
Costruito su EntityManager piuttosto che un metodo di repository condiviso-lib: il set di filtri è dinamico e l'aggiunta a kamo-shared-library avrebbe forzato una ricostruzione di arte comune su ogni consumatore per una query solo problemi DocsService. Il predicato dell'organizzazione è incondizionato e prima, e un test dimostra che sopravvive ogni combinazione di filtro — il punto finale non prende nessun parametro org, quindi una clausola di caduta elencare gli incarichi di un altro inquilino. Pagare trasporta un uid tie-break perché un 200-membro consegna scrive consegnatoA dentro un millisecondo. I documenti sono due GRUPPO Per domande, non 25 per-row lookups. Uno stato sconosciuto è un 400, mai un silenzio filtro ignorato su una griglia di conformità.
· DocsService
Assegnazioni di pacchetti legali Void, org-wide o per i membri nominati
Risultati per assegnazione — vuoti, superati, non fondati — perché un amministratore voiding un pacchetto per sei persone di nome deve sapere che aveva già eseguito (il loro bancarelle di prove) e che non sono mai state assegnate (un roster id stante). Un nudo 200 non può Dillo. Le transizioni di assegnazione sono sincronizzate: la riga di assegnazione, non lo stato di e-sign, è che porta il membro e guida il distintivo. I vuoti di busta vanno off-thread e sono prefiltrato su SIGNED/VOIDED, perché voidEnvelope 409s una busta completa e una solo il documento di riconoscimento non ha affatto busta. Un membro può contenere diverse righe dopo una riedizione, così ogni fila prende la propria decisione.
· DocsService
Redeliver un pacchetto modificato, sovrapponendo gli incarichi aperti
Rifiutata a meno che l'impronta live non differisca da quella pubblicata. Binder.dateaggiornamento è morto e Img non ha alcun contatore di revisione, in modo che l'impronta digitale è l'unico segnale di cambiamento c'è — senza il cancello, Redeliver è un pulsante che annulla silenziosamente tutti in-progresso lavoro e ristampa uno strumento identico. Pubblica attraverso il percorso di pubblicazione esistente (uno scrittore di righe di versione), segna ogni assegnazione OPEN SUPERSEDED, mette in coda le loro buste non terminal per il voiding, e riedizioni al set dei membri sovrapposti più chiunque altro nuovo abbinamento — ri-risolto attraverso findAudience in modo da un membro terminato dal momento che la prima consegna non ottiene alcun sostituto. Le assegnazioni eseguite sono intatte; sono le prove.
· DocsService
Consegnare un pacchetto legale al suo pubblico, dal thread richiesta
Pianificare sul thread richiesta (due domande a buon mercato, quindi la risposta è esatta su chi è incluso e chi è stato saltato e perché), scriverlo: 200 membri x 8 documenti è 1.600 righe più numerose chiamate ESigService, e DocsService serve WOPI. La piscina non è un fagiolo dell'esecutore di primavera. applicazioneTaskExecutor è E DocsService ha gia' messo a nudo @Async. KSessionService e DocumentService -- pubblicare un fagiolo Executor si muoverebbe silenziosamente la sessione WOPI toccare questa piccola piscina delimitata. Gli sviluppatori sono creati al di fuori di qualsiasi transazione; un timeout di lettura di 20s durante la detenzione di un La connessione Hikari è come una piscina di dieci stelle. Un documento firmabile la cui busta fallito mantiene una null wrap uid, che è l'unico segnale che la griglia ha. Anche le mappature redeliver/void/assignment-grid sbarcano qui, quindi il controller ha UNO autorizzazione imbuto scritto e provato una volta piuttosto che un secondo bullonato in seguito; i loro servizi rispondono 501 fino a Compiti 4-6 riempire i corpi.
· DocsService
Delivery planner — targeting incrementale, prefiltro e-mail, date di consegna
La consegna è il nuovo percorso ed è destinato a essere re-run, così i membri che già tengono un l'assegnazione viene sottratta piuttosto che data una seconda copia dello stesso strumento. I membri senza e-mail sono contati e saltati davanti, perché EsignEnvelopeService 400s un firmatario senza uno dall'interno del loop, dopo i membri precedenti già hanno buste vive. Il pubblico interroga OR tre predicati, così i duplicati sono crollati. Un solo documento di riconoscimento non riceve affatto alcuna busta.
· DocsService
Cliente interno ESigService per la consegna dei pacchetti legali
Il primo cliente in uscita di DocsService. Post a Non e' vero. (origine MANUAL, mai misurata) con soppressioneInvite=true — HR invia una notifica, non una per documento per membro. I timeout sono espliciti: EsignEmailClient costruisce un RestTemplate nudo con nessuno, e un leggere in tempo reale su un pod a cuneo perni un filo del lavoratore fino al riavvio. Niente getta su un errore a monte, perché il fan-out emette una chiamata per documento firmabile per membro e non deve interrompere il lotto su un modello cattivo. Void mappe 409 ad un reportabile ha lasciato il segno piuttosto che un errore. I record di risposta ignorano i campi sconosciuti — il contesto OggettoMapper ha ancora FAIL ON UNKNOWN PROPERTIES su.
· kamo-internal
Pacchetto Modelli sub-tab per legale e conformità
Sostituisce il corpo HrTabPlaceholder solo — il percorso, l'ingresso scheda e il cancello già esistono in hrTabs.ts. AG Grid Community list plus a create/edit dialogo con un raccoglitore di leganti ordinato per HR RESOURCE (ordinal 13, non id 15), up/down reorder, e Dipartimento / Tipo di lavoro multi-seleziona che gli All-Team-Members toggle disabilita. The L'etichetta di toggle è il termine membro del gruppo plurale di org, mai una stringa hardcoded. Nessun nuovo i18n chiavi: ogni etichetta riutilizza una chiave che il dizionario già definisce, e conta rendering da dati.
· kamo-internal
Pacchetti legali percorsi proxy, client api e helper puri
Thin 1:1 forwardToApi percorsi sotto /api/docs/legal — una richiesta a monte ciascuno, perché OTKAuthFilter fa ottenereAndDelete e un loop fan-out in un prossimo percorso sarebbe bisogno di un OTK per membro. Ids rimangono stringhe fine a fine (unique rowid). Reorder è bloccati piuttosto che avvolgere, e le liste del pubblico vengono inviate vuote quando All Team I membri sono così un pubblico più stretto stante non può tornare indietro.
· DocsService
Anteprima risoluzione Audience
Risolve un pubblico salvato o redatto tramite TeamMemberRepo.findAudience, che è il solo il lettore che trasporta il predicato obbligatorio di idoneità ACTIVE + recordState — il team-membri-appaltatori endpoint restituisce PROSPECT, CANDIDATE, TERMINATED e RESIGNED. Bandiere membri senza e-mail (EsignEnvelopeService hard-400s senza uno) e membri sotto la sicurezza TEAM MEMBER (ImagingController salta silenziosamente la copia archiviata). An il pubblico che mira nulla si risolve a nessuno, e le liste vuote id diventano sentinels così le clausole OR'd IN rimangono valide SQL.
· DocsService
Pubblicare congela una versione con i documenti stampati
Pins img dat id più un hash contenuto, non img id: saveImgContent ridefinisce lo stesso Img a nuovi byte su ogni Docs salvare, e risolvereSource cammina al dat live a sessione di costruzione e flatten. Esamina il design congelato invece di lasciare risolvereDesignJson rientrare nel nuovo, rifiuta un documento senza convertito PDF, e rifiuta una pubblicazione la cui impronta non si è spostata.
· DocsService
Pacchetto legale CRUD a /api/docs/legal/packages
Elenca, crea, ricevi, aggiorna ed elimina, con refs del legante ordinato e righe del pubblico sostituito come set. Org viene dalla sessione su ogni percorso — DocsService è consentireAll e OTKPreAuthFilter continua la catena senza un gettone, così il l'autenticazione. Dipartimento di Cross-org, titolo di lavoro, membro e legante ids 400 esplicitamente piuttosto che silenziosamente scrivere nulla.
· DocsService
Contratto del filo del pacchetto legale e richiesta di normalizzazione
Ids attraversano come stringhe (unique rowid supera MAX SAFE INTEGER). L'ordine di Binder è ordine elenco, de-duplicato, e una voce non numerica 400s piuttosto che essere saltato — saltare in silenzio è come un riordino perde un legante. Le liste del pubblico vuoto crollano a un sentinel così le clausole OR'd IN in findAudience rimangono valide SQL.
· DocsService
Impronta del contenuto per i pacchetti legali
Binder.dateUpdated non si muove mai dopo INSERT, quindi il contenuto di un pacchetto non cambia segnale da confrontare. Aggiunge una SHA-256 sopra il legante ordinata canonica/tem tuple — incluso imgDatId, perché saveImgContent ridefinisce lo stesso Img a nuovi byte su ogni documento salva — più il testo di attestazione hash. La codifica è prefissata così un configJson artigianale non può falsificare un layout diverso. Inoltre aggiunge com.kamo.z.shared.hr.legal alla scansione del repository.
· SecurityService
Push platform-admin state changes instead of being polled for them
Every platform screen backed by this service refreshed on a timer, because this service has no WebSocket and therefore no way to tell anyone anything: the closed-loan trainer tab re-read every 4 seconds while a run was live, DNS provisioning every 15, commerce sync logs and VOIP recording stats every 30, and the domain setup page asked verify-dns once a minute per open tab. PlatformEventPublisher sends these to core NATS and MediaService's new PlatformStompRelayController puts them on STOMP. Core NATS rather than JetStream, matching ThemeProvisionPublisher: this service's stream is CHAT_MESSAGES/chat.>, so a JetStream publish to security.* would fail expected-stream validation and be dropped. At-most-once is the right trade — every consumer also loads over REST when it mounts, so a lost event costs a refresh, never correctness. Wired at the points where the state actually moves: - ClosedLoanTrainerService on each progress write, on claim, and on every terminal state, so the monitor advances exactly when the walk does. - DnsProvisioningService as each record settles, rather than the panel re-reading the whole log hoping something landed. - RetailSyncLogBroadcaster on each sync-log row, via the new shared-lib listener seam, keyed by provider config so an org syncing several providers does not redraw all of them because one moved. Two counters have no such moment, and are handled honestly rather than pretended into events: - The VOIP recording backlog is written by another service entirely, so PlatformStatsWatcher samples it — but on the server, once, and it publishes only when the numbers actually change, so a quiet backlog produces no traffic where the old arrangement re-sent an identical payload to every viewer twice a minute forever. trigger-sync publishes immediately, since it knows the backlog is about to move. - Diagnostics is live JVM/host/database readings where essentially every field differs second to second, so there is nothing discrete to push. It gets a bare tick: one server timer deciding when "now" is worth re-reading, instead of one per open tab each pulling the full snapshot. DomainVerificationWatcher replaces the setup page's polling. DNS propagation and certificate issuance are genuinely external state with no event to subscribe to, so the checking has to happen somewhere — but not in every browser. One sweep covers every waiting domain, takes the 25 least-recently-checked so a backlog of misconfigured domains rotates instead of being re-queried in full, only probes HTTPS once DNS resolves, and publishes only when a domain actually advances. Two existing tests construct these classes directly and were updated for the new constructor parameters. Note: **************** fails on main already (unset EntityManager in the test's hand-built service) and is untouched by this change — verified against a clean HEAD worktree.
· EmailService
Pubblica gli eventi di mailbox-change in modo che le opinioni della posta smettano di inquinare
L'albero della cartella, la lista di conversazione e la lista dei messaggi hanno eseguito il proprio 30-secondo timer, ricaricando la possibilità che qualcosa si fosse mosso. Il WebSocket già ha detto loro quando la posta è arrivata, ma questo è solo uno dei modi in cui una casella di posta cambia — leggere un messaggio in Roundcube o su un telefono, spostarlo, cancellarlo, o Esprimere tutto ha lasciato l'UI sbagliato fino alla prossima spunta. EmailMailboxChanged dice che una cartella non è più quello che stai mostrando, e trasporta il motivo per cui un consumatore può ignorare i tipi di cui non importa. Pubblicato il E-mail.changed. ascoltatori IDLE (arrivi, expunge, cambio bandiera) e dal testo, bandiere, spostare, eliminare, spam, inviare e redigere endpoint. Deliberatamente non piegato in EmailUnreadPublisher: che uno possiede un conteggio, quindi deve raggiungere il fornitore e carbonesce esplosioni per rimanere a prezzi accessibili. Questo porta non conta e non legge nulla, quindi è abbastanza economico da inviare ogni cambiamento e non deve aspettare dietro una finestra un conteggio ha bisogno. Una mossa segnala nessuna cartella perché tocca due e la fonte non è sempre noto al chiamante — i consumatori trattano che come "ricaricare qualsiasi cosa si sta mostrando".
· MediaService
Relay SecurityService eventi piattaforma su STOMP
SecurityService possiede la superficie platform-admin — configurazione di sistema, DNS provisioning, sincronizzazione del commercio — ma non ha WebSocket endpoint, quindi ogni schermo sostenuto da esso non aveva modo di essere detto nulla e rinfrescato su un timer invece: la scheda del formatore chiuso ogni 4 secondi, il provisioning DNS ogni 15, il commercio registri di sincronizzazione e statistiche di registrazione VOIP ogni 30. Pubblica al core NATS; questo mette quei messaggi su STOMP, lo stesso SupportoStompRelayController e ************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************ già uso. Il soggetto a destinazione è meccanico — abbandonare la "sicurezza" principale e scambiare dots for slashes, così security.dns.log.42 arriva su /topic/dns/log/42 — che significa che un nuovo tipo di evento ha bisogno di un editore e un abbonato e niente qui. I prefissi sono vincolati esplicitamente piuttosto che come sicurezza. >: un catch-all sicurezza a doppio carico. già relè allo stesso tema forma.
· kamo-shared-library
Lasci il progresso di sincronizzazione e lo stato di dominio essere annunciato invece di inquinato
Due ganci per la conversione push in SecurityService, dove diverse piattaforme schermi rinfrescati su timer perché non c'era modo di dire loro nulla. RetailSyncLogListener è una cucitura di notifica opzionale su RetailSync Orchestrator, chiamato quando una corsa di sincronizzazione scrive la sua riga IN PROGRESS e di nuovo quando scrive terminale uno. L'orchestratore rimane ignaro di come la notifica viaggia, e con nessuna implementazione registrata si comporta esattamente come prima. La sincronizzazione del fornitore cruscotto ricaricato la sua intera lista di registro ogni 30 secondi per guardare un run che aveva appena ha cominciato da solo. E' il momento giusto. elenca domini di alto livello che non hanno finito in arrivo — DNS non verificato, o verificato senza certificato confermato. Esiste per un visualizzatore di verifica lato server: la pagina di configurazione di dominio inquinata verifica-dns una volta al minuto per aprire scheda mentre aspetta la propagazione DNS pubblica e l'emissione. Ordinato meno recently-controllato prima e preso con un Pageable Limitare così una spazzata non può crescere con il numero di domini non verificati in modo permanente.
· ESigService
Consentire a un mittente di sopprimere il per-envelope invitare e-mail
Creare una busta incondizionatamente inviato un invito, quindi un chiamante lotto molti le buste dietro una notifica non hanno avuto modo di rimanere tranquillo. Null conserva il comportamento esistente; l'accesso al token è ancora rilasciato in entrambi i modi.
· EmailService
Push INBOX unread counts over NATS/WebSocket instead of polling
The nav-top mail badge in kamo-internal refreshed itself by calling /api/email/folders every 30 seconds, per browser tab. That endpoint walks the entire folder tree and opens every folder read-only to answer, so the cost of one integer was a full mailbox summary, repeated indefinitely. The WebSocket that already existed only announced that mail had arrived and carried no count, so its one job was to trigger another poll. Publish the count itself: - EmailUnreadSnapshot on NATS email.unread.<addr>, relayed to STOMP /topic/email/unread/<memberId>. NATS is in the path because the pod that observes a change is routinely not the pod holding the member's WebSocket. - EmailUnreadPublisher coalesces per mailbox, so a ten-message IDLE delivery or a page of mail marked read is one IMAP round trip and one publish, off the caller's thread. - MailReader.getUnreadCount reads one folder. Graph answers it from the folder list it already returns; IMAP-backed providers override it with a single STATUS (UNSEEN). - A snapshot is published on subscribe, on IDLE messagesAdded/messagesRemoved, on IMAP flag changes, and from the mark-read / flags / move / delete / spam endpoints. Three gaps this also closes: - Flag changes were invisible. Reading mail in Roundcube or on a phone sets \Seen without adding or removing a message, so the badge only ever fell when the browser next polled. IDLE now carries a MessageChangedListener. - Cloud mailboxes got no push at all. EmailWebSocketController resolved credentials through the KamoMail virtual_users table, which has no row for a member on Microsoft 365 or Google Workspace, so subscribe() logged a warning and returned. It now resolves through MailProviderResolver, and IDLE connects with the credential spec (host/port/TLS/XOAUTH2) via a shared ImapStoreFactory.connect rather than assuming the KamoMail host and a password. - Sessions leaked. A closed tab never sends /email/unsubscribe, so mailboxes are now reference counted per STOMP session and released on SessionDisconnectEvent. Mailboxes with no live IDLE listener — Graph, past the 50-connection cap, or a dead IDLE thread — are swept server-side every 60s and published to the same topic. That replaces per-tab polling rather than push: one sweep serves every tab a member has open, membership is re-tested each pass so a dead listener is picked up, and the browser still receives the count over the WebSocket. MessageIndexer binds email.> and deserialized everything on it as a message, so it now skips subjects outside email.inbox. — filtered in the handler rather than by narrowing the subscription, because email-metadata-indexer is a durable consumer and changing its filter subject would reject the subscribe on every pod until the durable was deleted by hand.
· InitializerService
Avviare lo schema del pacchetto legale
Aggiunge com.kamo.z.shared.hr.legal alla lista di scansione del repository e assicura il unicità e indici di ricerca l'entità mappatura non può esprimere in modo sicuro.
· kamo-shared-library
Certificato di attestazione del pacchetto di registrazione come prova di solo append
Il pacchetto-livello 'Ho letto e d'accordo' è un diverso strumento giuridico il consenso E-SIGN a tradurre e da qualsiasi firma per documento, ed è la prova SOLO per un pacchetto senza documenti firmabili. Le guardie rifiutano l'aggiornamento ed eliminare il modo in cui PhiAccessLog fa.

Il tuo universo ti sta aspettando.
Aggiungi i prodotti quando sei pronto: nessuna migrazione, nessun nuovo login, nessuna richiesta di pagamento.
Gratis per sempre — nessuna carta di credito richiesta