DéveloppeursDocsFournisseurs
Yeria
Documentation

YeriaUI & YeriaApp

Les deux points d'entrée du SDK : construire, puis signer.

Description

Le SDK expose deux objets aux fournisseurs. Le partage se fait selon qui détient le secret.

ObjetDétient une clé ?Rôle
YeriaUINonFabrique de vues. Construit des vues typées. Pure, sans état, jamais instanciée — utilisée comme Math ou JSON.
YeriaAppOui (Ed25519)Tout ce qui exige la clé privée : signer les vues, vérifier les jetons utilisateurs entrants, notifier, effectuer la rotation de clé.

Construire ne demande pas de clé ; signer, si. Vous construisez une vue avec YeriaUI, puis vous la passez à app.serve(view) — un transfert de rôle, pas un aller-retour sur un même objet.

Tout le reste (YeriaSigner, YeriaPublicKeys, le client de plateforme, les vérificateurs) est interne. Ce n'est pas exporté et vous n'avez pas à y toucher.

javascript
1import { YeriaUI, YeriaApp } from '@numerum-tech/yeriasdk';
2
3const app = new YeriaApp({
4    appId: process.env.YERIA_APP_ID,
5    baseUrl: process.env.YERIA_BASE_URL,
6    privateKey: process.env.SERVICE_ED25519_PRIVATE_KEY,
7});
8
9const view = YeriaUI.createFormView('registration', 'User Registration')
10    .addTextField('name', 'Name', true)
11    .submitButton('Register', 'POST');
12
13return app.serve(view);   // → { payload, signature }

Les deux systèmes de clés

Ne les confondez pas : ils couvrent deux sens de circulation différents.

CléAlgorithmeDétenteurRôle
Clé de plateforme YeriaRSA (RS256)YeriaSigne les jetons utilisateurs que reçoit votre backend. Vous ne faites que vérifier avec elle — le SDK la récupère et la met en cache pour vous.
Clé de votre serviceEd25519VousSigne les enveloppes de vue que vous renvoyez, ainsi que vos appels vers Yeria. La moitié publique est enregistrée sur votre service ; la privée ne quitte jamais votre backend.

app.verifyUserToken() rejette tout jeton dont l'en-tête alg n'est pas RS256. Les enveloppes de vue et les enveloppes signées par un fournisseur sont toujours en Ed25519.


YeriaUI — la fabrique de vues

Sans clé. Importez et utilisez directement : il n'y a pas de constructeur.

Méthodes de fabrique

Chacune renvoie un nouveau constructeur de vue typée.

  • createFormView(formId: string, title: string, processId?: string): FormView
  • createReaderView(viewId: string, title: string, processId?: string): ReaderView
  • createActionListView(viewId: string, title: string, processId?: string): ActionListView
  • createActionGridView(viewId: string, title: string, processId?: string): ActionGridView
  • createIconGridView(viewId: string, title: string, processId?: string): IconGridView
  • createQRScanView(viewId: string, title: string, processId?: string): QRScanView
  • createQRDisplayView(viewId: string, title: string, processId?: string): QRDisplayView
  • createMessageView(viewId: string, title: string, processId?: string): MessageView
  • createCardView(viewId: string, title: string, processId?: string): CardView
  • createCarouselView(viewId: string, title: string, processId?: string): CarouselView
  • createTimelineView(viewId: string, title: string, processId?: string): TimelineView
  • createMediaView(viewId: string, title: string, processId?: string): MediaView
  • createMapView(viewId: string, title: string, processId?: string): MapView

Reconstituer une vue stockée

javascript
1fromJson(json: Record<string, unknown>): BaseView

Transforme du JSON de transport (un gabarit statique, ou une vue que vous avez persistée dans votre base) en une instance de vue typée et validée. À utiliser quand vous stockez vos écrans en JSON plutôt que de les reconstruire champ par champ :

javascript
1const view = YeriaUI.fromJson(await db.screens.get('home'));
2return app.serve(view);

Corps d'erreur non signé

javascript
1error(spec: ProviderErrorSpec): ProviderErrorBody

Construit un corps d'erreur byte-identique à celui de la plateforme, mais sans signature. À utiliser quand aucune clé n'est disponible (échec au démarrage, erreur de configuration). Si vous avez une clé, préférez app.serveError() : une erreur signée est une erreur à laquelle le mobile peut se fier.


YeriaApp — le détenteur de la clé

Configuration

appIdstringrequis
Identifiant unique de l'application. Transporté dans chaque charge utile signée.
privateKeystringoptionnel
Clé privée Ed25519, au format PEM (PKCS#8). Générée à la volée si omise — acceptable en test, jamais en production.
publicKeystringoptionnel
Clé publique Ed25519, au format PEM (SPKI). Dérivée de privateKey si omise.
baseUrlstringoptionnel
URL de base de Yeria, par exemple https://yeria.app. Nécessaire pour verifyUserToken, notify, fetchUserDetails, rotateKey.
allowedDomainsstring[]optionnel
Domaines autorisés pour la diffusion des vues (par défaut []).
viewExpirationMinutesnumberoptionnel
Durée de vie d'une vue, utilisée par verifyIntegrity (par défaut 60).
notificationTimeoutnumberoptionnel
Délai HTTP en millisecondes pour les appels à la plateforme (par défaut 5000).

Servir des vues

javascript
1serve(view: BaseView): SignedEnvelope

Signe une vue dans une enveloppe v3. C'est l'unique chemin de signature — renvoyez le résultat tel quel :

javascript
1res.json(app.serve(view));
javascript
1serveError(spec: ProviderErrorSpec): SignedEnvelope

Même enveloppe, portant une erreur au lieu d'une vue. Le mobile vérifie la signature avant d'afficher quoi que ce soit : une erreur signée ne peut donc pas être falsifiée par un attaquant sur le réseau. Le champ status est indicatif — le mobile ne se fie pas au code HTTP.

SignedEnvelope

javascript
1{
2  payload: string,     // JSON string: {"appId":…,"timestamp":…,"view":{…}}
3  signature: string    // Ed25519 signature over the payload STRING BYTES, base64
4}

La signature porte sur les octets exacts de payload. Un vérificateur doit contrôler ces octets avant d'analyser le JSON : re-sérialiser d'abord modifierait les octets et invaliderait la signature.

Vérification et clés

verifyIntegrity(envelope: SignedEnvelope)boolean
Vérifie une enveloppe signée par cette application. Lève une erreur si l'appId ne correspond pas, si la vue a expiré ou si la signature est invalide.
getServicePublicKey()string
Clé publique Ed25519 de votre service (PEM). C'est la valeur à enregistrer sur votre service Yeria.

Jetons utilisateurs entrants

javascript
1async verifyUserToken(
2    bearerToken: string,
3    expectedAudience?: string | number,
4): Promise<YeriaTokenClaims>

Vérifie un jeton utilisateur émis par Yeria (RS256). Résout le kid du jeton contre les clés publiques de Yeria via un magasin interne à cache TTL — vous n'avez ni résolveur à câbler ni PEM à détenir. Impose iss='yeria' et exp > now ; passez expectedAudience pour épingler le jeton sur l'identifiant de votre service.

Lève YeriaPlatformUnreachableError quand Yeria est injoignable (renvoyez 503 — le jeton est peut-être valide). Une clé inconnue ou expirée remonte comme une erreur de vérification (renvoyez 401).

Profil utilisateur

javascript
1async fetchUserDetails(opts: {
2    userServiceToken: string;
3    fetch?: typeof fetch;
4}): Promise<UserDetails>

Récupère le profil d'un utilisateur Yeria, autorisé par le jeton de service vivant de l'utilisateur lui-même — ni par vos préférences de notification, ni par un jeton porteur placé dans le corps. Le justificatif transmis est la signature Ed25519 de l'enveloppe.

Notifications

signNotification(notification: Notification)SecureNotificationResponse
Signe sans envoyer.
async notify(notification: Notification)Promise<void>
Signe et envoie en POST à Yeria.

Voir Notifications pour les règles de distribution et les erreurs d'abonnement.

Rotation de clé

javascript
1async rotateKey(...)

Enregistre une nouvelle clé publique Ed25519 pour votre service. L'ancienne reste valide pendant une courte période de grâce, pour ne pas casser les requêtes en cours.

Échappatoires statiques

Préférez les méthodes d'instance. Celles-ci existent pour le cas rare où vous détenez déjà le PEM exact, ou ne voulez aucun appel réseau.

static verifySignature(publicKey, payload, signature, onError?)
Vérification Ed25519 brute d'une chaîne de charge utile contre un PEM.
static signView(view, appId, privateKey, timestamp?)
Signe une vue en SignedEnvelope à partir d'une clé ponctuelle.
static verifyYeriaToken(jwt, yeriaPublicKey, expectedAudience?)
Vérifie un jeton utilisateur contre un PEM connu. Pur, sans réseau.
static async verifyYeriaTokenWithResolver(jwt, resolver, expectedAudience?)
Idem, mais c'est vous qui fournissez le résolveur de kid.

Exemple complet

javascript
1import express from 'express';
2import { YeriaUI, YeriaApp } from '@numerum-tech/yeriasdk';
3
4const app = new YeriaApp({
5    appId: process.env.YERIA_APP_ID,
6    baseUrl: process.env.YERIA_BASE_URL,
7    privateKey: process.env.SERVICE_ED25519_PRIVATE_KEY,
8});
9
10const server = express();
11
12server.get('/screens/registration', async (req, res) => {
13    const bearer = (req.headers.authorization ?? '').replace(/^Bearer /i, '');
14
15    try {
16        const claims = await app.verifyUserToken(bearer, process.env.YERIA_SERVICE_ID);
17
18        const form = YeriaUI.createFormView('registration', 'User Registration')
19            .setIntro(`Welcome, ${claims.sub}`)
20            .addTextField('name', 'Name', true)
21            .addEmailField('email', 'Email', true)
22            .submitButton('Register', 'POST');
23
24        return res.json(app.serve(form));
25    } catch (err) {
26        return res.status(401).json(app.serveError({
27            code: 'auth.invalid_token',
28            message: 'Session expirée, reconnectez-vous.',
29            status: 401,
30        }));
31    }
32});

La charge utile reçue par le mobile :

json
1{
2  "payload": "{\"appId\":\"my-app\",\"timestamp\":1706443200000,\"view\":{\"id\":\"registration\",\"type\":\"Form\",\"content\":{…}}}",
3  "signature": "MEUCIQD…"
4}

Voir aussi