@hgdc/auth 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -111,13 +111,18 @@ Le claim `organizations` n'est lu qu'à la création d'une session (étape 1 ci-
111
111
  - Barre et menu des produits (`@hgdc/ui/products`) : `https://<mot>.hgdc.ch/auth/hgdc?refresh=1&next=/`. Chaque passage d'un produit à l'autre resynchronise.
112
112
  - Page d'une organisation inconnue du produit (ou dont la personne n'est pas membre localement) : une seule redirection vers `hgdcRefreshPath("/o/acme")` avant d'afficher « introuvable ». Au retour, `next` porte `?synced=1` : `hasSyncedMarker(location.search)` vrai, la page affiche « introuvable » au lieu de relancer. L'entrée elle-même ne relance jamais un `next` déjà marqué : pas de boucle.
113
113
 
114
- ```ts
115
- import { hasSyncedMarker, hgdcRefreshPath } from "@hgdc/auth"
114
+ ```tsx
115
+ // Côté client, une fois les organisations chargées
116
+ import { useOrganizationRefresh } from "@hgdc/auth/react"
116
117
 
117
- if (org === null && !hasSyncedMarker(window.location.search)) {
118
- window.location.replace(hgdcRefreshPath(`/o/${slug}`))
119
- return null
120
- }
118
+ const refreshing = useOrganizationRefresh(viewer !== undefined && !space)
119
+ if (refreshing) return <FamilyLoader page />
120
+ if (!space) return <NotFound />
121
+
122
+ // Dans un loader ou un beforeLoad (rendu serveur compris)
123
+ import { hasSyncedMarker, hgdcRefreshPath } from "@hgdc/auth"
124
+ if (!organization && !hasSyncedMarker(location.searchStr))
125
+ throw redirect({ href: hgdcRefreshPath(location.href), reloadDocument: true })
121
126
  ```
122
127
 
123
128
  - L'ancienne session n'est pas révoquée : si Account ne répond pas, la personne garde son accès, et la session expire seule (`SESSION_TTL_SECONDS`).
package/dist/react.d.ts CHANGED
@@ -52,3 +52,18 @@ export declare function HgdcMark({ className }: {
52
52
  * `className`, l'état d'attente est exposé par `aria-busy` et `data-pending`.
53
53
  */
54
54
  export declare function HgdcSignInButton({ authClient, callbackURL, errorCallbackURL, onError, label, disabled, ...rest }: HgdcSignInButtonProps): ReactElement;
55
+ /**
56
+ * Page d'une organisation inconnue du produit, ou dont la personne n'est pas membre dans sa copie :
57
+ * une invitation acceptée dans Account n'y arrive qu'à la session suivante (ADR 0013). Quand
58
+ * `unknown` est vrai, part une fois vers `/auth/hgdc?refresh=1&next=<page>` et rend `true` (afficher
59
+ * un chargement). Au retour (`?synced=1`), rend `false` : afficher « introuvable ».
60
+ *
61
+ * Côté client seulement : à appeler une fois la liste des organisations chargée.
62
+ *
63
+ * ```tsx
64
+ * const refreshing = useOrganizationRefresh(viewer !== undefined && !space)
65
+ * if (refreshing) return <FamilyLoader page />
66
+ * if (!space) return <NotFound />
67
+ * ```
68
+ */
69
+ export declare function useOrganizationRefresh(unknown: boolean): boolean;
package/dist/react.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState } from "react";
3
- import { HGDC_PROVIDER_ID } from "./index.js";
2
+ import { useEffect, useState } from "react";
3
+ import { HGDC_PROVIDER_ID, hasSyncedMarker, hgdcRefreshPath } from "./index.js";
4
4
  /**
5
5
  * Part vers HGDC Account. Renvoie `{ ok: true }` quand la redirection est lancée,
6
6
  * sinon l'erreur du client ou du réseau, sans lever.
@@ -50,3 +50,28 @@ export function HgdcSignInButton({ authClient, callbackURL = "/", errorCallbackU
50
50
  }
51
51
  return (_jsxs("button", { ...rest, type: "button", disabled: disabled === true || pending, "aria-busy": pending, "data-pending": pending ? "" : undefined, onClick: () => void signIn(), children: [_jsx(HgdcMark, {}), _jsx("span", { children: pending ? "Redirection vers Account…" : label })] }));
52
52
  }
53
+ /**
54
+ * Page d'une organisation inconnue du produit, ou dont la personne n'est pas membre dans sa copie :
55
+ * une invitation acceptée dans Account n'y arrive qu'à la session suivante (ADR 0013). Quand
56
+ * `unknown` est vrai, part une fois vers `/auth/hgdc?refresh=1&next=<page>` et rend `true` (afficher
57
+ * un chargement). Au retour (`?synced=1`), rend `false` : afficher « introuvable ».
58
+ *
59
+ * Côté client seulement : à appeler une fois la liste des organisations chargée.
60
+ *
61
+ * ```tsx
62
+ * const refreshing = useOrganizationRefresh(viewer !== undefined && !space)
63
+ * if (refreshing) return <FamilyLoader page />
64
+ * if (!space) return <NotFound />
65
+ * ```
66
+ */
67
+ export function useOrganizationRefresh(unknown) {
68
+ const synced = typeof window === "undefined" || hasSyncedMarker(window.location.search);
69
+ const refreshing = unknown && !synced;
70
+ useEffect(() => {
71
+ if (!refreshing)
72
+ return;
73
+ const { pathname, search, hash } = window.location;
74
+ window.location.replace(hgdcRefreshPath(`${pathname}${search}${hash}`));
75
+ }, [refreshing]);
76
+ return refreshing;
77
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hgdc/auth",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "Connexion HGDC : bouton « Se connecter avec HGDC », config better-auth et gardes Convex.",
5
5
  "license": "UNLICENSED",
6
6
  "homepage": "https://github.com/hugogebel-boop/hgdc-kit/tree/main/packages/auth#readme",