@orangecheck/me-client 0.37.0 → 0.38.0

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
@@ -249,7 +249,7 @@ app.get('/api/me', (c) => {
249
249
 
250
250
  ### Sessions ended everywhere
251
251
 
252
- Set `OC_PROJECT_KEY` and `OC_SIGNING_SECRET` (from ochk.app/me/projects) and `getOcSession`, `withOcAuth`, `ocAuthExpress` and `ocAuthHono` refuse a session the person ended everywhere: sign out everywhere, a passkey removed, the account deleted. A sign-in token carries `rh`, its revocation handle for your origin; they look it up in me.ochk.io's list of ended handles for that origin, read once a minute per origin with a request signed by your secret, so a refusal lands within about two minutes. The handles name nobody, and another site's handles for the same person never match yours. If the list can't be read, or is more than ten minutes old by its own clock, reads go on and writes are refused until it can. A token without `rh`, and every token while the two variables are unset, is checked by its signature alone and stays valid until it expires. Needs 0.35.0 or later.
252
+ Set `OC_PROJECT_KEY` and `OC_SIGNING_SECRET` (from ochk.app/me/projects) and `getOcSession`, `withOcAuth`, `ocAuthExpress` and `ocAuthHono` refuse a session the person ended everywhere: sign out everywhere, a passkey removed, the account deleted. A sign-in token carries `rh`, its revocation handle for your origin; they look it up in me.ochk.io's list of ended handles for that origin, read once a minute per origin with a request signed by your secret, so a refusal lands within about two minutes. The handles name nobody, and another site's handles for the same person never match yours. If the list can't be read, or is more than ten minutes old by its own clock, reads go on and writes are refused until it can: the adapters answer such a write `503 { reason: 'revocations_unavailable' }` (0.38.0), not 401, so a client retries instead of signing the person out, and `checkOcSession(headers, options)` tells the same apart for your own code (`signed_in`, `signed_out` or `unavailable`). A token without `rh`, and every token while the two variables are unset, is checked by its signature alone and stays valid until it expires. Needs 0.35.0 or later.
253
253
 
254
254
  ## Browser popup signin
255
255
 
package/dist/server.d.mts CHANGED
@@ -10,6 +10,15 @@ interface OcSessionOptions extends VerifyOcOptions {
10
10
  }
11
11
  declare function _resetSessionChecksForTests(): void;
12
12
  declare function getOcSession(headers: SessionRequestHeaders | Headers, options?: OcSessionOptions): Promise<SessionPayload | null>;
13
+ type OcSessionCheck = {
14
+ status: 'signed_in';
15
+ session: SessionPayload;
16
+ } | {
17
+ status: 'signed_out';
18
+ } | {
19
+ status: 'unavailable';
20
+ };
21
+ declare function checkOcSession(headers: SessionRequestHeaders | Headers, options?: OcSessionOptions): Promise<OcSessionCheck>;
13
22
  interface NextApiRequestLike {
14
23
  method?: string;
15
24
  headers: {
@@ -80,4 +89,4 @@ interface HonoContextLike {
80
89
  type HonoNextLike = () => Promise<void>;
81
90
  declare function ocAuthHono(options?: WithOcAuthOptions): (c: HonoContextLike, next: HonoNextLike) => Promise<unknown>;
82
91
 
83
- export { BACK_ACCOUNT_URL, type OcHonoEnv, type OcSessionOptions, type WithOcAuthOptions, type WithOcSession, _resetSessionChecksForTests, getOcSession, ocAuthExpress, ocAuthHono, withOcAuth };
92
+ export { BACK_ACCOUNT_URL, type OcHonoEnv, type OcSessionCheck, type OcSessionOptions, type WithOcAuthOptions, type WithOcSession, _resetSessionChecksForTests, checkOcSession, getOcSession, ocAuthExpress, ocAuthHono, withOcAuth };
package/dist/server.d.ts CHANGED
@@ -10,6 +10,15 @@ interface OcSessionOptions extends VerifyOcOptions {
10
10
  }
11
11
  declare function _resetSessionChecksForTests(): void;
12
12
  declare function getOcSession(headers: SessionRequestHeaders | Headers, options?: OcSessionOptions): Promise<SessionPayload | null>;
13
+ type OcSessionCheck = {
14
+ status: 'signed_in';
15
+ session: SessionPayload;
16
+ } | {
17
+ status: 'signed_out';
18
+ } | {
19
+ status: 'unavailable';
20
+ };
21
+ declare function checkOcSession(headers: SessionRequestHeaders | Headers, options?: OcSessionOptions): Promise<OcSessionCheck>;
13
22
  interface NextApiRequestLike {
14
23
  method?: string;
15
24
  headers: {
@@ -80,4 +89,4 @@ interface HonoContextLike {
80
89
  type HonoNextLike = () => Promise<void>;
81
90
  declare function ocAuthHono(options?: WithOcAuthOptions): (c: HonoContextLike, next: HonoNextLike) => Promise<unknown>;
82
91
 
83
- export { BACK_ACCOUNT_URL, type OcHonoEnv, type OcSessionOptions, type WithOcAuthOptions, type WithOcSession, _resetSessionChecksForTests, getOcSession, ocAuthExpress, ocAuthHono, withOcAuth };
92
+ export { BACK_ACCOUNT_URL, type OcHonoEnv, type OcSessionCheck, type OcSessionOptions, type WithOcAuthOptions, type WithOcSession, _resetSessionChecksForTests, checkOcSession, getOcSession, ocAuthExpress, ocAuthHono, withOcAuth };
package/dist/server.js CHANGED
@@ -600,15 +600,22 @@ function _resetSessionChecksForTests() {
600
600
  warnedUnchecked = false;
601
601
  }
602
602
  async function getOcSession(headers, options = {}) {
603
+ const checked = await checkOcSession(headers, options);
604
+ return checked.status === "signed_in" ? checked.session : null;
605
+ }
606
+ async function checkOcSession(headers, options = {}) {
603
607
  const session = await authCore.getOcSession(headers, options);
604
608
  if (!session) {
605
609
  if (options.audience === void 0) warnIfAudienceMissing(headers);
606
- return null;
610
+ return { status: "signed_out" };
607
611
  }
608
612
  const check = revocationFor(options);
609
- if (check && await check.refuses(session, options.method)) return null;
610
- return session;
613
+ if (check && await check.refuses(session, options.method)) {
614
+ return await check.status(session) === "revoked" ? { status: "signed_out" } : { status: "unavailable" };
615
+ }
616
+ return { status: "signed_in", session };
611
617
  }
618
+ var UNAVAILABLE = { status: 503, body: { ok: false, reason: "revocations_unavailable" } };
612
619
  var warnedAudience = false;
613
620
  function warnIfAudienceMissing(headers) {
614
621
  if (warnedAudience) return;
@@ -727,16 +734,17 @@ function withOcAuth(handler, options = {}) {
727
734
  return async (req, res) => {
728
735
  res.setHeader("Cache-Control", "no-store, private");
729
736
  res.setHeader("Vary", "Cookie, Authorization");
730
- const session = await getOcSession(
737
+ const checked = await checkOcSession(
731
738
  {
732
739
  cookie: typeof req.headers.cookie === "string" ? req.headers.cookie : null,
733
740
  authorization: typeof req.headers.authorization === "string" ? req.headers.authorization : null
734
741
  },
735
742
  { ...options, method: req.method }
736
743
  );
744
+ const session = checked.status === "signed_in" ? checked.session : null;
737
745
  const withSession = req;
738
746
  withSession.ocSession = session;
739
- const refused = await refusal(session, options);
747
+ const refused = checked.status === "unavailable" ? UNAVAILABLE : await refusal(session, options);
740
748
  if (refused) return res.status(refused.status).json(refused.body);
741
749
  return handler(withSession, res);
742
750
  };
@@ -746,15 +754,16 @@ function ocAuthExpress(options = {}) {
746
754
  try {
747
755
  res.setHeader("Cache-Control", "no-store, private");
748
756
  res.setHeader("Vary", "Cookie, Authorization");
749
- const session = await getOcSession(
757
+ const checked = await checkOcSession(
750
758
  {
751
759
  cookie: typeof req.headers.cookie === "string" ? req.headers.cookie : null,
752
760
  authorization: typeof req.headers.authorization === "string" ? req.headers.authorization : null
753
761
  },
754
762
  { ...options, method: req.method }
755
763
  );
764
+ const session = checked.status === "signed_in" ? checked.session : null;
756
765
  req.ocSession = session;
757
- const refused = await refusal(session, options);
766
+ const refused = checked.status === "unavailable" ? UNAVAILABLE : await refusal(session, options);
758
767
  if (refused) {
759
768
  res.status(refused.status).json(refused.body);
760
769
  return;
@@ -769,12 +778,13 @@ function ocAuthHono(options = {}) {
769
778
  return async (c, next) => {
770
779
  c.header("Cache-Control", "no-store, private");
771
780
  c.header("Vary", "Cookie, Authorization");
772
- const session = await getOcSession(c.req.raw.headers, {
781
+ const checked = await checkOcSession(c.req.raw.headers, {
773
782
  ...options,
774
783
  method: c.req.raw.method
775
784
  });
785
+ const session = checked.status === "signed_in" ? checked.session : null;
776
786
  c.set("ocSession", session);
777
- const refused = await refusal(session, options);
787
+ const refused = checked.status === "unavailable" ? UNAVAILABLE : await refusal(session, options);
778
788
  if (refused) return c.json(refused.body, refused.status);
779
789
  await next();
780
790
  };
@@ -794,6 +804,7 @@ Object.defineProperty(exports, "verifyOcToken", {
794
804
  });
795
805
  exports.BACK_ACCOUNT_URL = BACK_ACCOUNT_URL;
796
806
  exports._resetSessionChecksForTests = _resetSessionChecksForTests;
807
+ exports.checkOcSession = checkOcSession;
797
808
  exports.getOcSession = getOcSession;
798
809
  exports.identity = identity;
799
810
  exports.ocAuthExpress = ocAuthExpress;