@civitai/blocks-react 0.5.1 → 0.6.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/dist/hooks/useRequestConsent.d.ts +24 -0
- package/dist/hooks/useRequestConsent.d.ts.map +1 -0
- package/dist/hooks/useRequestConsent.js +30 -0
- package/dist/hooks/useRequestConsent.js.map +1 -0
- package/dist/hooks/useRequestSignIn.d.ts +20 -0
- package/dist/hooks/useRequestSignIn.d.ts.map +1 -0
- package/dist/hooks/useRequestSignIn.js +26 -0
- package/dist/hooks/useRequestSignIn.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/iframeTransport.d.ts +1 -1
- package/dist/internal/iframeTransport.d.ts.map +1 -1
- package/dist/internal/iframeTransport.js +7 -3
- package/dist/internal/iframeTransport.js.map +1 -1
- package/dist/internal/originMatcher.d.ts +28 -0
- package/dist/internal/originMatcher.d.ts.map +1 -0
- package/dist/internal/originMatcher.js +89 -0
- package/dist/internal/originMatcher.js.map +1 -0
- package/package.json +11 -11
- package/LICENSE +0 -21
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy consent. Asks the host to open civitai.com's consent UI when a
|
|
3
|
+
* LOGGED-IN viewer clicks an action whose consent-gated scope the block token
|
|
4
|
+
* is missing — e.g. the block's Generate button needs `ai:write:budgeted` /
|
|
5
|
+
* `buzz:read:self` but the viewer hasn't granted them yet (so the mint withheld
|
|
6
|
+
* them and `useBlockToken().scopes` doesn't include them). The host validates
|
|
7
|
+
* the message like every inbound one (origin + `event.source` pinned, only
|
|
8
|
+
* honored after BLOCK_READY) and opens its consent UI.
|
|
9
|
+
*
|
|
10
|
+
* `scopes` is an optional advisory hint of which scopes the action needs; the
|
|
11
|
+
* host independently grants the missing set it computed at mint, so the block
|
|
12
|
+
* can omit it.
|
|
13
|
+
*
|
|
14
|
+
* Fire-and-forget: the host doesn't reply. On grant the host re-mints the block
|
|
15
|
+
* token and pushes a TOKEN_REFRESH carrying the now-granted scopes — observe
|
|
16
|
+
* `useBlockToken().scopes` and retry the action once the scope appears. Mirrors
|
|
17
|
+
* {@link useRequestSignIn} (the anonymous-conversion analog).
|
|
18
|
+
*/
|
|
19
|
+
export declare function useRequestConsent(): {
|
|
20
|
+
requestConsent: (payload?: {
|
|
21
|
+
scopes?: string[];
|
|
22
|
+
}) => void;
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=useRequestConsent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRequestConsent.d.ts","sourceRoot":"","sources":["../../src/hooks/useRequestConsent.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,IAAI;IACnC,cAAc,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,IAAI,CAAC;CAC3D,CAQA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import { getTransport } from '../internal/singleton.js';
|
|
3
|
+
/**
|
|
4
|
+
* Lazy consent. Asks the host to open civitai.com's consent UI when a
|
|
5
|
+
* LOGGED-IN viewer clicks an action whose consent-gated scope the block token
|
|
6
|
+
* is missing — e.g. the block's Generate button needs `ai:write:budgeted` /
|
|
7
|
+
* `buzz:read:self` but the viewer hasn't granted them yet (so the mint withheld
|
|
8
|
+
* them and `useBlockToken().scopes` doesn't include them). The host validates
|
|
9
|
+
* the message like every inbound one (origin + `event.source` pinned, only
|
|
10
|
+
* honored after BLOCK_READY) and opens its consent UI.
|
|
11
|
+
*
|
|
12
|
+
* `scopes` is an optional advisory hint of which scopes the action needs; the
|
|
13
|
+
* host independently grants the missing set it computed at mint, so the block
|
|
14
|
+
* can omit it.
|
|
15
|
+
*
|
|
16
|
+
* Fire-and-forget: the host doesn't reply. On grant the host re-mints the block
|
|
17
|
+
* token and pushes a TOKEN_REFRESH carrying the now-granted scopes — observe
|
|
18
|
+
* `useBlockToken().scopes` and retry the action once the scope appears. Mirrors
|
|
19
|
+
* {@link useRequestSignIn} (the anonymous-conversion analog).
|
|
20
|
+
*/
|
|
21
|
+
export function useRequestConsent() {
|
|
22
|
+
const requestConsent = useCallback((payload) => {
|
|
23
|
+
getTransport().sendMessage({
|
|
24
|
+
type: 'REQUEST_CONSENT',
|
|
25
|
+
...(payload ? { payload } : {}),
|
|
26
|
+
});
|
|
27
|
+
}, []);
|
|
28
|
+
return { requestConsent };
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=useRequestConsent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRequestConsent.js","sourceRoot":"","sources":["../../src/hooks/useRequestConsent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,iBAAiB;IAG/B,MAAM,cAAc,GAAG,WAAW,CAAC,CAAC,OAA+B,EAAE,EAAE;QACrE,YAAY,EAAE,CAAC,WAAW,CAAC;YACzB,IAAI,EAAE,iBAAiB;YACvB,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChC,CAAC,CAAC;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,OAAO,EAAE,cAAc,EAAE,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anonymous conversion. Asks the host to start civitai.com's login flow when a
|
|
3
|
+
* logged-out viewer (`useBlockContext().viewer === null`) clicks an action that
|
|
4
|
+
* needs auth/money — e.g. the block's Generate button. The host validates the
|
|
5
|
+
* message like every inbound one (origin + `event.source` pinned, only honored
|
|
6
|
+
* after BLOCK_READY) and opens its login UI.
|
|
7
|
+
*
|
|
8
|
+
* `returnUrl` is an optional same-origin in-app path to return to after sign-in;
|
|
9
|
+
* the host sanitises it (rejecting absolute / protocol-relative values) and
|
|
10
|
+
* defaults to the current page when omitted.
|
|
11
|
+
*
|
|
12
|
+
* Fire-and-forget: the host doesn't reply. After login the page reloads / the
|
|
13
|
+
* block re-inits as an authenticated viewer.
|
|
14
|
+
*/
|
|
15
|
+
export declare function useRequestSignIn(): {
|
|
16
|
+
requestSignIn: (payload?: {
|
|
17
|
+
returnUrl?: string;
|
|
18
|
+
}) => void;
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=useRequestSignIn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRequestSignIn.d.ts","sourceRoot":"","sources":["../../src/hooks/useRequestSignIn.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,IAAI;IAClC,aAAa,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAC3D,CAQA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import { getTransport } from '../internal/singleton.js';
|
|
3
|
+
/**
|
|
4
|
+
* Anonymous conversion. Asks the host to start civitai.com's login flow when a
|
|
5
|
+
* logged-out viewer (`useBlockContext().viewer === null`) clicks an action that
|
|
6
|
+
* needs auth/money — e.g. the block's Generate button. The host validates the
|
|
7
|
+
* message like every inbound one (origin + `event.source` pinned, only honored
|
|
8
|
+
* after BLOCK_READY) and opens its login UI.
|
|
9
|
+
*
|
|
10
|
+
* `returnUrl` is an optional same-origin in-app path to return to after sign-in;
|
|
11
|
+
* the host sanitises it (rejecting absolute / protocol-relative values) and
|
|
12
|
+
* defaults to the current page when omitted.
|
|
13
|
+
*
|
|
14
|
+
* Fire-and-forget: the host doesn't reply. After login the page reloads / the
|
|
15
|
+
* block re-inits as an authenticated viewer.
|
|
16
|
+
*/
|
|
17
|
+
export function useRequestSignIn() {
|
|
18
|
+
const requestSignIn = useCallback((payload) => {
|
|
19
|
+
getTransport().sendMessage({
|
|
20
|
+
type: 'REQUEST_SIGN_IN',
|
|
21
|
+
...(payload ? { payload } : {}),
|
|
22
|
+
});
|
|
23
|
+
}, []);
|
|
24
|
+
return { requestSignIn };
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=useRequestSignIn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRequestSignIn.js","sourceRoot":"","sources":["../../src/hooks/useRequestSignIn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,gBAAgB;IAG9B,MAAM,aAAa,GAAG,WAAW,CAAC,CAAC,OAAgC,EAAE,EAAE;QACrE,YAAY,EAAE,CAAC,WAAW,CAAC;YACzB,IAAI,EAAE,iBAAiB;YACvB,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChC,CAAC,CAAC;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,OAAO,EAAE,aAAa,EAAE,CAAC;AAC3B,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export { useBlockResize } from './hooks/useBlockResize.js';
|
|
|
21
21
|
export { useBuzzPurchase } from './hooks/useBuzzPurchase.js';
|
|
22
22
|
export { useCheckpointPicker } from './hooks/useCheckpointPicker.js';
|
|
23
23
|
export { useCivitaiNavigate } from './hooks/useCivitaiNavigate.js';
|
|
24
|
+
export { useRequestSignIn } from './hooks/useRequestSignIn.js';
|
|
25
|
+
export { useRequestConsent } from './hooks/useRequestConsent.js';
|
|
24
26
|
export { useBlockAnalytics } from './hooks/useBlockAnalytics.js';
|
|
25
27
|
export { useAppStorage } from './hooks/useAppStorage.js';
|
|
26
28
|
export type { AppStorageKeyEntry, AppStorageListResult, AppStorageQuota, UseAppStorage, } from './hooks/useAppStorage.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,YAAY,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAE5E,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAEhE,OAAO,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAC3F,YAAY,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EACV,aAAa,EACb,cAAc,EACd,eAAe,GAChB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,YAAY,EACV,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,EACf,aAAa,GACd,MAAM,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,YAAY,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAE5E,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAEhE,OAAO,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAC3F,YAAY,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EACV,aAAa,EACb,cAAc,EACd,eAAe,GAChB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,YAAY,EACV,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,EACf,aAAa,GACd,MAAM,0BAA0B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -19,6 +19,8 @@ export { useBlockResize } from './hooks/useBlockResize.js';
|
|
|
19
19
|
export { useBuzzPurchase } from './hooks/useBuzzPurchase.js';
|
|
20
20
|
export { useCheckpointPicker } from './hooks/useCheckpointPicker.js';
|
|
21
21
|
export { useCivitaiNavigate } from './hooks/useCivitaiNavigate.js';
|
|
22
|
+
export { useRequestSignIn } from './hooks/useRequestSignIn.js';
|
|
23
|
+
export { useRequestConsent } from './hooks/useRequestConsent.js';
|
|
22
24
|
export { useBlockAnalytics } from './hooks/useBlockAnalytics.js';
|
|
23
25
|
export { useAppStorage } from './hooks/useAppStorage.js';
|
|
24
26
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAGhE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAEhE,OAAO,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAG3F,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAO3D,QAAQ;AACR,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAGhE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAEhE,OAAO,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAG3F,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAO3D,QAAQ;AACR,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC"}
|
|
@@ -20,7 +20,7 @@ export interface IframeTransportOptions {
|
|
|
20
20
|
* correlates request/response pairs by `requestId`.
|
|
21
21
|
*/
|
|
22
22
|
export declare class IframeTransport implements BlockTransport {
|
|
23
|
-
private readonly
|
|
23
|
+
private readonly originMatcher;
|
|
24
24
|
private readonly window;
|
|
25
25
|
private snapshot;
|
|
26
26
|
private readonly listeners;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iframeTransport.d.ts","sourceRoot":"","sources":["../../src/internal/iframeTransport.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EAEzB,KAAK,wBAAwB,EAC9B,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"iframeTransport.d.ts","sourceRoot":"","sources":["../../src/internal/iframeTransport.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EAEzB,KAAK,wBAAwB,EAC9B,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AASxB,MAAM,WAAW,sBAAsB;IACrC;;;;;;;OAOG;IACH,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AASD;;;;;GAKG;AACH,qBAAa,eAAgB,YAAW,cAAc;IACpD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAEhC,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IAEnD,yEAAyE;IACzE,OAAO,CAAC,YAAY,CAAuB;IAE3C,2EAA2E;IAC3E,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiD;IAC1E,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAE7D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA4B;IACxD,OAAO,CAAC,WAAW,CAAuC;IAC1D,OAAO,CAAC,UAAU,CAAwB;IAC1C,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,YAAY,CAAS;IAE7B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAgC;gBAEpD,IAAI,EAAE,sBAAsB;IAoCxC,WAAW,IAAI,aAAa;IAI5B,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAO3C,WAAW,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAIxC,WAAW,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI;IAIhD,WAAW,CACT,OAAO,EAAE,eAAe,EACxB,YAAY,EAAE,wBAAwB,EACtC,IAAI,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GAChC,OAAO,CAAC,OAAO,CAAC;IAmBnB,uDAAuD;IACvD,OAAO,IAAI,IAAI;IAWf,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,aAAa;IA2FrB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,IAAI;CAGb"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isMessage, } from '@civitai/app-sdk/blocks';
|
|
2
2
|
import { EMPTY_SNAPSHOT, nextRequestId, snapshotFromInit, tokenFromWrapped, } from './transport.js';
|
|
3
|
+
import { OriginMatcher } from './originMatcher.js';
|
|
3
4
|
import { payloadValidatorFor } from './validate.js';
|
|
4
5
|
const INIT_TIMEOUT_MS = 10_000;
|
|
5
6
|
const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
|
|
@@ -10,7 +11,7 @@ const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
|
|
|
10
11
|
* correlates request/response pairs by `requestId`.
|
|
11
12
|
*/
|
|
12
13
|
export class IframeTransport {
|
|
13
|
-
|
|
14
|
+
originMatcher;
|
|
14
15
|
window;
|
|
15
16
|
snapshot = EMPTY_SNAPSHOT;
|
|
16
17
|
listeners = new Set();
|
|
@@ -30,7 +31,10 @@ export class IframeTransport {
|
|
|
30
31
|
throw new Error('IframeTransport: allowedParentOrigins must contain at least one entry. ' +
|
|
31
32
|
'Configure NEXT_PUBLIC_BLOCK_ALLOWED_PARENT_ORIGINS (or the framework equivalent).');
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
+
// Build the matcher from the allowlist. Exact entries match by equality;
|
|
35
|
+
// `https://*.example.com` entries match any subdomain on a dot boundary
|
|
36
|
+
// (mirrors the host-side CSP frame-ancestors convention).
|
|
37
|
+
this.originMatcher = new OriginMatcher(opts.allowedParentOrigins);
|
|
34
38
|
this.window = opts.window ?? globalThis.window;
|
|
35
39
|
if (!this.window) {
|
|
36
40
|
throw new Error('IframeTransport: no window available; cannot mount on the server.');
|
|
@@ -111,7 +115,7 @@ export class IframeTransport {
|
|
|
111
115
|
this.window.parent.postMessage(msg, this.parentOrigin);
|
|
112
116
|
}
|
|
113
117
|
handleMessage(event) {
|
|
114
|
-
if (!this.
|
|
118
|
+
if (!this.originMatcher.matches(event.origin))
|
|
115
119
|
return;
|
|
116
120
|
const data = event.data;
|
|
117
121
|
if (data == null || typeof data !== 'object' || typeof data.type !== 'string')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iframeTransport.js","sourceRoot":"","sources":["../../src/internal/iframeTransport.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,GAKV,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GAIjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAIpD,MAAM,eAAe,GAAG,MAAM,CAAC;AAC/B,MAAM,0BAA0B,GAAG,MAAM,CAAC;AAuB1C;;;;;GAKG;AACH,MAAM,OAAO,eAAe;IACT,
|
|
1
|
+
{"version":3,"file":"iframeTransport.js","sourceRoot":"","sources":["../../src/internal/iframeTransport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Origin allowlist matching for {@link IframeTransport}.
|
|
3
|
+
*
|
|
4
|
+
* Each `allowedParentOrigins` entry is either:
|
|
5
|
+
* - an EXACT origin (`https://civitai.com`) — matched by string equality, or
|
|
6
|
+
* - a SUFFIX-WILDCARD origin (`https://*.civitaic.com`) — matches any
|
|
7
|
+
* `https://<sub>.civitaic.com`, where `<sub>` is one or more labels
|
|
8
|
+
* (single-label `pr-9` or a full subtree `a.b`), but NOT the bare apex
|
|
9
|
+
* `https://civitaic.com` and NOT a different registrable domain.
|
|
10
|
+
*
|
|
11
|
+
* The wildcard form mirrors the host-side CSP `frame-ancestors` convention
|
|
12
|
+
* (`https://*.civitaic.com`) so a single block build can trust both prod
|
|
13
|
+
* (`civitai.com`, an exact entry) and dynamic preview subdomains
|
|
14
|
+
* (`pr-N.civitaic.com`, a wildcard entry).
|
|
15
|
+
*
|
|
16
|
+
* Security: matching is scheme-pinned and suffix-anchored on a DOT boundary,
|
|
17
|
+
* so `https://*.civitaic.com` does NOT match `https://civitaic.com.attacker.tld`
|
|
18
|
+
* (different suffix) nor `https://evilcivitaic.com` (no dot boundary). A
|
|
19
|
+
* bare `*` or empty wildcard is rejected at construction.
|
|
20
|
+
*/
|
|
21
|
+
export declare class OriginMatcher {
|
|
22
|
+
private readonly exact;
|
|
23
|
+
private readonly wildcards;
|
|
24
|
+
constructor(allowedParentOrigins: readonly string[]);
|
|
25
|
+
/** True when `origin` is allowed by an exact or wildcard allowlist entry. */
|
|
26
|
+
matches(origin: string): boolean;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=originMatcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"originMatcher.d.ts","sourceRoot":"","sources":["../../src/internal/originMatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AASH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsB;IAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA2B;gBAEzC,oBAAoB,EAAE,SAAS,MAAM,EAAE;IAoBnD,6EAA6E;IAC7E,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;CAkBjC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Origin allowlist matching for {@link IframeTransport}.
|
|
3
|
+
*
|
|
4
|
+
* Each `allowedParentOrigins` entry is either:
|
|
5
|
+
* - an EXACT origin (`https://civitai.com`) — matched by string equality, or
|
|
6
|
+
* - a SUFFIX-WILDCARD origin (`https://*.civitaic.com`) — matches any
|
|
7
|
+
* `https://<sub>.civitaic.com`, where `<sub>` is one or more labels
|
|
8
|
+
* (single-label `pr-9` or a full subtree `a.b`), but NOT the bare apex
|
|
9
|
+
* `https://civitaic.com` and NOT a different registrable domain.
|
|
10
|
+
*
|
|
11
|
+
* The wildcard form mirrors the host-side CSP `frame-ancestors` convention
|
|
12
|
+
* (`https://*.civitaic.com`) so a single block build can trust both prod
|
|
13
|
+
* (`civitai.com`, an exact entry) and dynamic preview subdomains
|
|
14
|
+
* (`pr-N.civitaic.com`, a wildcard entry).
|
|
15
|
+
*
|
|
16
|
+
* Security: matching is scheme-pinned and suffix-anchored on a DOT boundary,
|
|
17
|
+
* so `https://*.civitaic.com` does NOT match `https://civitaic.com.attacker.tld`
|
|
18
|
+
* (different suffix) nor `https://evilcivitaic.com` (no dot boundary). A
|
|
19
|
+
* bare `*` or empty wildcard is rejected at construction.
|
|
20
|
+
*/
|
|
21
|
+
export class OriginMatcher {
|
|
22
|
+
exact;
|
|
23
|
+
wildcards;
|
|
24
|
+
constructor(allowedParentOrigins) {
|
|
25
|
+
const exact = new Set();
|
|
26
|
+
const wildcards = [];
|
|
27
|
+
for (const raw of allowedParentOrigins) {
|
|
28
|
+
const entry = raw.trim();
|
|
29
|
+
if (!entry)
|
|
30
|
+
continue;
|
|
31
|
+
const wildcard = parseWildcard(entry);
|
|
32
|
+
if (wildcard) {
|
|
33
|
+
wildcards.push(wildcard);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
exact.add(entry);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
this.exact = exact;
|
|
40
|
+
this.wildcards = wildcards;
|
|
41
|
+
}
|
|
42
|
+
/** True when `origin` is allowed by an exact or wildcard allowlist entry. */
|
|
43
|
+
matches(origin) {
|
|
44
|
+
if (this.exact.has(origin))
|
|
45
|
+
return true;
|
|
46
|
+
for (const wc of this.wildcards) {
|
|
47
|
+
if (!origin.startsWith(wc.scheme))
|
|
48
|
+
continue;
|
|
49
|
+
const host = origin.slice(wc.scheme.length);
|
|
50
|
+
// Reject anything with a path/port/query smuggled into the host span:
|
|
51
|
+
// a real `event.origin` is scheme + host (+ optional :port). We require
|
|
52
|
+
// an exact host-suffix match with at least one leading label, and no '/'.
|
|
53
|
+
if (host.includes('/'))
|
|
54
|
+
continue;
|
|
55
|
+
// The host must END with the dot-anchored suffix AND have at least one
|
|
56
|
+
// character of label before the leading dot (so the apex itself is excluded).
|
|
57
|
+
if (host.length > wc.suffix.length && host.endsWith(wc.suffix)) {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Parses a `https://*.example.com`-style entry into `{scheme, suffix}`.
|
|
66
|
+
* Returns `null` for non-wildcard (exact) entries.
|
|
67
|
+
* Throws for malformed wildcards (`*` only, `https://*`, `https://*.`).
|
|
68
|
+
*/
|
|
69
|
+
function parseWildcard(entry) {
|
|
70
|
+
const star = entry.indexOf('*');
|
|
71
|
+
if (star === -1)
|
|
72
|
+
return null;
|
|
73
|
+
// Wildcard must be of the exact form `<scheme>://*.<suffix>`.
|
|
74
|
+
const marker = '://*.';
|
|
75
|
+
const markerAt = entry.indexOf(marker);
|
|
76
|
+
if (markerAt === -1) {
|
|
77
|
+
throw new Error(`IframeTransport: invalid wildcard origin "${entry}". ` +
|
|
78
|
+
'Wildcard entries must look like "https://*.example.com".');
|
|
79
|
+
}
|
|
80
|
+
const scheme = entry.slice(0, markerAt + 3); // include "://"
|
|
81
|
+
const bareSuffix = entry.slice(markerAt + marker.length); // after "://*."
|
|
82
|
+
if (!scheme || scheme === '://' || !bareSuffix) {
|
|
83
|
+
throw new Error(`IframeTransport: invalid wildcard origin "${entry}". ` +
|
|
84
|
+
'A wildcard needs a scheme and a non-empty domain suffix, e.g. "https://*.example.com".');
|
|
85
|
+
}
|
|
86
|
+
// Dot-anchor the suffix so `*.civitaic.com` only matches on a label boundary.
|
|
87
|
+
return { scheme, suffix: `.${bareSuffix}` };
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=originMatcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"originMatcher.js","sourceRoot":"","sources":["../../src/internal/originMatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AASH,MAAM,OAAO,aAAa;IACP,KAAK,CAAsB;IAC3B,SAAS,CAA2B;IAErD,YAAY,oBAAuC;QACjD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;QAChC,MAAM,SAAS,GAAoB,EAAE,CAAC;QAEtC,KAAK,MAAM,GAAG,IAAI,oBAAoB,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;YACzB,IAAI,CAAC,KAAK;gBAAE,SAAS;YAErB,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;YACtC,IAAI,QAAQ,EAAE,CAAC;gBACb,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED,6EAA6E;IAC7E,OAAO,CAAC,MAAc;QACpB,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;QAExC,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAChC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC;gBAAE,SAAS;YAC5C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC5C,sEAAsE;YACtE,wEAAwE;YACxE,0EAA0E;YAC1E,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,SAAS;YACjC,uEAAuE;YACvE,8EAA8E;YAC9E,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC/D,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AAED;;;;GAIG;AACH,SAAS,aAAa,CAAC,KAAa;IAClC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,IAAI,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAE7B,8DAA8D;IAC9D,MAAM,MAAM,GAAG,OAAO,CAAC;IACvB,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CACb,6CAA6C,KAAK,KAAK;YACrD,0DAA0D,CAC7D,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB;IAC7D,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,gBAAgB;IAC1E,IAAI,CAAC,MAAM,IAAI,MAAM,KAAK,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CACb,6CAA6C,KAAK,KAAK;YACrD,wFAAwF,CAC3F,CAAC;IACJ,CAAC;IAED,8EAA8E;IAC9E,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,UAAU,EAAE,EAAE,CAAC;AAC9C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@civitai/blocks-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "React hooks and iframe transport for Civitai App Blocks. Pairs with @civitai/app-sdk/blocks.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -24,14 +24,21 @@
|
|
|
24
24
|
"dist",
|
|
25
25
|
"README.md"
|
|
26
26
|
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc -p tsconfig.json",
|
|
29
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
30
|
+
"test": "vitest run",
|
|
31
|
+
"test:watch": "vitest"
|
|
32
|
+
},
|
|
27
33
|
"engines": {
|
|
28
34
|
"node": ">=20"
|
|
29
35
|
},
|
|
30
36
|
"peerDependencies": {
|
|
31
|
-
"@civitai/app-sdk": "
|
|
37
|
+
"@civitai/app-sdk": ">=0.7.0 <1",
|
|
32
38
|
"react": "^18.0.0 || ^19.0.0"
|
|
33
39
|
},
|
|
34
40
|
"devDependencies": {
|
|
41
|
+
"@civitai/app-sdk": "workspace:^",
|
|
35
42
|
"@testing-library/react": "^16.0.0",
|
|
36
43
|
"@types/node": "^25.9.1",
|
|
37
44
|
"@types/react": "^19.2.15",
|
|
@@ -39,8 +46,7 @@
|
|
|
39
46
|
"react": "^19.0.0",
|
|
40
47
|
"react-dom": "^19.0.0",
|
|
41
48
|
"typescript": "^5.9.2",
|
|
42
|
-
"vitest": "^4.1.7"
|
|
43
|
-
"@civitai/app-sdk": "^0.8.0"
|
|
49
|
+
"vitest": "^4.1.7"
|
|
44
50
|
},
|
|
45
51
|
"publishConfig": {
|
|
46
52
|
"access": "public"
|
|
@@ -59,11 +65,5 @@
|
|
|
59
65
|
"type": "git",
|
|
60
66
|
"url": "git+https://github.com/civitai/civitai-app-starters.git",
|
|
61
67
|
"directory": "packages/civitai-blocks-react"
|
|
62
|
-
},
|
|
63
|
-
"scripts": {
|
|
64
|
-
"build": "tsc -p tsconfig.json",
|
|
65
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
66
|
-
"test": "vitest run",
|
|
67
|
-
"test:watch": "vitest"
|
|
68
68
|
}
|
|
69
|
-
}
|
|
69
|
+
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Civitai
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|