@orangecheck/me-client 0.36.1 → 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 +2 -2
- package/dist/server.d.mts +10 -1
- package/dist/server.d.ts +10 -1
- package/dist/server.js +22 -10
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +22 -11
- package/dist/server.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -90,7 +90,7 @@ export default withOcAuth(handler, {
|
|
|
90
90
|
});
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
-
Or set it in code with `requireBond: { minSats: 100_000, minDays: 30, maxAgeSecs: 3600 }`. ochk.io re-checks the coin when its last check is over ten minutes old; `maxAgeSecs` refuses a claim checked longer ago than you accept. From 0.28.0, an account below the floor gets `403 { ok: false, reason: 'bond_required', need: { min_sats, min_days }, have: { sats_floor, days_floor } | null, back_url }`: link the person to `back_url` to back their account. If the project's setting can't be read
|
|
93
|
+
Or set it in code with `requireBond: { minSats: 100_000, minDays: 30, maxAgeSecs: 3600 }`. ochk.io re-checks the coin when its last check is over ten minutes old; `maxAgeSecs` refuses a claim checked longer ago than you accept. From 0.28.0, an account below the floor gets `403 { ok: false, reason: 'bond_required', need: { min_sats, min_days }, have: { sats_floor, days_floor } | null, back_url }`: link the person to `back_url` to back their account. If the project's setting can't be read, the last one read stands for ten minutes; with none read in that time, a signed-in request gets `503 { reason: 'bond_policy_unavailable' }` rather than being let through unchecked. A request with no session is not held to the project's setting and never waits on it (0.37.0); pass `required: true` to answer it 401. `readBondClaim(session)` and `bondMeets(session, { minSats, minDays, maxAgeSecs })` are exported for your own checks.
|
|
94
94
|
|
|
95
95
|
## Pay your users, when you choose to
|
|
96
96
|
|
|
@@ -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
|
|
610
|
+
return { status: "signed_out" };
|
|
607
611
|
}
|
|
608
612
|
const check = revocationFor(options);
|
|
609
|
-
if (check && await check.refuses(session, options.method))
|
|
610
|
-
|
|
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;
|
|
@@ -690,10 +697,11 @@ async function bondNeed(options) {
|
|
|
690
697
|
return null;
|
|
691
698
|
}
|
|
692
699
|
async function refusal(session, options) {
|
|
693
|
-
const need = await bondNeed(options);
|
|
694
700
|
if (!session && options.required) {
|
|
695
701
|
return { status: 401, body: { ok: false, reason: "unauthenticated" } };
|
|
696
702
|
}
|
|
703
|
+
if (!session && !options.requireBond) return null;
|
|
704
|
+
const need = await bondNeed(options);
|
|
697
705
|
if (need === UNKNOWN_PROJECT) {
|
|
698
706
|
return { status: 500, body: { ok: false, reason: "unknown_project_key" } };
|
|
699
707
|
}
|
|
@@ -726,16 +734,17 @@ function withOcAuth(handler, options = {}) {
|
|
|
726
734
|
return async (req, res) => {
|
|
727
735
|
res.setHeader("Cache-Control", "no-store, private");
|
|
728
736
|
res.setHeader("Vary", "Cookie, Authorization");
|
|
729
|
-
const
|
|
737
|
+
const checked = await checkOcSession(
|
|
730
738
|
{
|
|
731
739
|
cookie: typeof req.headers.cookie === "string" ? req.headers.cookie : null,
|
|
732
740
|
authorization: typeof req.headers.authorization === "string" ? req.headers.authorization : null
|
|
733
741
|
},
|
|
734
742
|
{ ...options, method: req.method }
|
|
735
743
|
);
|
|
744
|
+
const session = checked.status === "signed_in" ? checked.session : null;
|
|
736
745
|
const withSession = req;
|
|
737
746
|
withSession.ocSession = session;
|
|
738
|
-
const refused = await refusal(session, options);
|
|
747
|
+
const refused = checked.status === "unavailable" ? UNAVAILABLE : await refusal(session, options);
|
|
739
748
|
if (refused) return res.status(refused.status).json(refused.body);
|
|
740
749
|
return handler(withSession, res);
|
|
741
750
|
};
|
|
@@ -745,15 +754,16 @@ function ocAuthExpress(options = {}) {
|
|
|
745
754
|
try {
|
|
746
755
|
res.setHeader("Cache-Control", "no-store, private");
|
|
747
756
|
res.setHeader("Vary", "Cookie, Authorization");
|
|
748
|
-
const
|
|
757
|
+
const checked = await checkOcSession(
|
|
749
758
|
{
|
|
750
759
|
cookie: typeof req.headers.cookie === "string" ? req.headers.cookie : null,
|
|
751
760
|
authorization: typeof req.headers.authorization === "string" ? req.headers.authorization : null
|
|
752
761
|
},
|
|
753
762
|
{ ...options, method: req.method }
|
|
754
763
|
);
|
|
764
|
+
const session = checked.status === "signed_in" ? checked.session : null;
|
|
755
765
|
req.ocSession = session;
|
|
756
|
-
const refused = await refusal(session, options);
|
|
766
|
+
const refused = checked.status === "unavailable" ? UNAVAILABLE : await refusal(session, options);
|
|
757
767
|
if (refused) {
|
|
758
768
|
res.status(refused.status).json(refused.body);
|
|
759
769
|
return;
|
|
@@ -768,12 +778,13 @@ function ocAuthHono(options = {}) {
|
|
|
768
778
|
return async (c, next) => {
|
|
769
779
|
c.header("Cache-Control", "no-store, private");
|
|
770
780
|
c.header("Vary", "Cookie, Authorization");
|
|
771
|
-
const
|
|
781
|
+
const checked = await checkOcSession(c.req.raw.headers, {
|
|
772
782
|
...options,
|
|
773
783
|
method: c.req.raw.method
|
|
774
784
|
});
|
|
785
|
+
const session = checked.status === "signed_in" ? checked.session : null;
|
|
775
786
|
c.set("ocSession", session);
|
|
776
|
-
const refused = await refusal(session, options);
|
|
787
|
+
const refused = checked.status === "unavailable" ? UNAVAILABLE : await refusal(session, options);
|
|
777
788
|
if (refused) return c.json(refused.body, refused.status);
|
|
778
789
|
await next();
|
|
779
790
|
};
|
|
@@ -793,6 +804,7 @@ Object.defineProperty(exports, "verifyOcToken", {
|
|
|
793
804
|
});
|
|
794
805
|
exports.BACK_ACCOUNT_URL = BACK_ACCOUNT_URL;
|
|
795
806
|
exports._resetSessionChecksForTests = _resetSessionChecksForTests;
|
|
807
|
+
exports.checkOcSession = checkOcSession;
|
|
796
808
|
exports.getOcSession = getOcSession;
|
|
797
809
|
exports.identity = identity;
|
|
798
810
|
exports.ocAuthExpress = ocAuthExpress;
|