@owlmeans/web-client 0.1.18-rc.2 → 0.1.18-rc.21
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 +16 -13
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/web-client/SKILL.md +70 -11
- package/build/components/dispatcher/component.d.ts.map +1 -1
- package/build/components/dispatcher/component.js +54 -9
- package/build/components/dispatcher/component.js.map +1 -1
- package/build/components/dispatcher/parametrise.d.ts.map +1 -1
- package/build/components/dispatcher/types.d.ts +2 -2
- package/build/components/dispatcher/types.d.ts.map +1 -1
- package/build/context.d.ts.map +1 -1
- package/build/context.js +2 -1
- package/build/context.js.map +1 -1
- package/build/entrypoints.d.ts +2 -0
- package/build/entrypoints.d.ts.map +1 -0
- package/build/entrypoints.js +18 -0
- package/build/entrypoints.js.map +1 -0
- package/build/errors.d.ts.map +1 -1
- package/build/errors.js.map +1 -1
- package/build/exports.d.ts +1 -0
- package/build/exports.d.ts.map +1 -1
- package/build/helper.d.ts.map +1 -1
- package/build/i18n/auth-be.json +32 -0
- package/build/i18n/auth-de.json +32 -0
- package/build/i18n/auth-en.json +32 -0
- package/build/i18n/auth-es.json +32 -0
- package/build/i18n/auth-pl.json +32 -0
- package/build/i18n/auth-ru.json +32 -0
- package/build/i18n/auth-uk.json +32 -0
- package/build/index.d.ts +2 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +2 -1
- package/build/index.js.map +1 -1
- package/build/login/consts.d.ts +11 -0
- package/build/login/consts.d.ts.map +1 -0
- package/build/login/consts.js +11 -0
- package/build/login/consts.js.map +1 -0
- package/build/login/index.d.ts +8 -0
- package/build/login/index.d.ts.map +1 -0
- package/build/login/index.js +8 -0
- package/build/login/index.js.map +1 -0
- package/build/login/pump.d.ts +20 -0
- package/build/login/pump.d.ts.map +1 -0
- package/build/login/pump.js +46 -0
- package/build/login/pump.js.map +1 -0
- package/build/login/redirect.d.ts +9 -0
- package/build/login/redirect.d.ts.map +1 -0
- package/build/login/redirect.js +47 -0
- package/build/login/redirect.js.map +1 -0
- package/build/login/screen.d.ts +15 -0
- package/build/login/screen.d.ts.map +1 -0
- package/build/login/screen.js +97 -0
- package/build/login/screen.js.map +1 -0
- package/build/login/service.d.ts +10 -0
- package/build/login/service.d.ts.map +1 -0
- package/build/login/service.js +17 -0
- package/build/login/service.js.map +1 -0
- package/build/login/surrogate.d.ts +21 -0
- package/build/login/surrogate.d.ts.map +1 -0
- package/build/login/surrogate.js +144 -0
- package/build/login/surrogate.js.map +1 -0
- package/build/login/view.d.ts +26 -0
- package/build/login/view.d.ts.map +1 -0
- package/build/login/view.js +73 -0
- package/build/login/view.js.map +1 -0
- package/build/main.d.ts +9 -1
- package/build/main.d.ts.map +1 -1
- package/build/main.js +9 -1
- package/build/main.js.map +1 -1
- package/build/middleware.d.ts.map +1 -1
- package/build/middleware.js +7 -6
- package/build/middleware.js.map +1 -1
- package/build/service.d.ts.map +1 -1
- package/build/service.js +1 -1
- package/build/service.js.map +1 -1
- package/build/types.d.ts +2 -1
- package/build/types.d.ts.map +1 -1
- package/package.json +17 -17
- package/src/components/dispatcher/component.tsx +72 -8
- package/src/components/dispatcher/types.ts +2 -2
- package/src/context.ts +2 -2
- package/src/entrypoints.ts +20 -0
- package/src/exports.ts +1 -0
- package/src/i18n/auth-be.json +32 -0
- package/src/i18n/auth-de.json +32 -0
- package/src/i18n/auth-en.json +32 -0
- package/src/i18n/auth-es.json +32 -0
- package/src/i18n/auth-pl.json +32 -0
- package/src/i18n/auth-ru.json +32 -0
- package/src/i18n/auth-uk.json +32 -0
- package/src/index.ts +2 -1
- package/src/login/consts.ts +12 -0
- package/src/login/index.ts +7 -0
- package/src/login/pump.ts +53 -0
- package/src/login/redirect.ts +59 -0
- package/src/login/screen.tsx +119 -0
- package/src/login/service.ts +19 -0
- package/src/login/surrogate.ts +175 -0
- package/src/login/view.tsx +94 -0
- package/src/main.tsx +11 -2
- package/src/middleware.ts +7 -6
- package/src/service.ts +1 -1
- package/src/types.ts +2 -1
- package/build/modules.d.ts +0 -2
- package/build/modules.d.ts.map +0 -1
- package/build/modules.js +0 -8
- package/build/modules.js.map +0 -1
- package/src/modules.ts +0 -9
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { adoptToken, clearSurrogate, markSurrogate, revokeToken, surrogatePath, LoginIntent, LoginOutcome, LOGIN_LOGOUT_MESSAGE, LOGIN_SURROGATE_FEATURES, LOGIN_SURROGATE_NAME, LOGIN_TOKEN_MESSAGE, } from '@owlmeans/client-auth/login';
|
|
2
|
+
import { SURROGATE_LOGIN, SURROGATE_LOGIN_PRIORITY } from './consts.js';
|
|
3
|
+
import { awaitSurrogate } from './pump.js';
|
|
4
|
+
/**
|
|
5
|
+
* Login for a document that cannot complete the flow where it is.
|
|
6
|
+
*
|
|
7
|
+
* An app embedded in a frame cannot redirect to an identity provider: the provider refuses to be
|
|
8
|
+
* embedded (`frame-ancestors`), and its session cookies are third-party there. So the flow runs
|
|
9
|
+
* one window up, in a surrogate window that is top-level and first-party on this application's own
|
|
10
|
+
* origin — where the very same flow completes normally — and the token is passed back to the
|
|
11
|
+
* document that asked for it.
|
|
12
|
+
*
|
|
13
|
+
* This plugin is deliberately not OIDC-specific. The mechanic is "run the login route one window
|
|
14
|
+
* up and hand the token back", and the adoption is the plain auth service, so any relying party
|
|
15
|
+
* that renders a login route gets it by registering nothing.
|
|
16
|
+
*
|
|
17
|
+
* `match` covers BOTH halves of the lifecycle — the framed opener and the surrogate itself, where
|
|
18
|
+
* `embedded` is false. Inside the surrogate the redirect plugin must not win: that window IS
|
|
19
|
+
* top-level, so it authorizes by an ordinary redirect and differs only in what it does with the
|
|
20
|
+
* token at the end.
|
|
21
|
+
*/
|
|
22
|
+
export const makeSurrogateLoginPlugin = () => {
|
|
23
|
+
/**
|
|
24
|
+
* Give the token to whoever is entitled to it, and get out of the way.
|
|
25
|
+
*
|
|
26
|
+
* Shared by `complete` (a token was just issued here) and `resume` (one was already here),
|
|
27
|
+
* because what happens to it is the same in both cases and only the question differs.
|
|
28
|
+
*/
|
|
29
|
+
const handBack = async (token, env) => {
|
|
30
|
+
if (!env.surrogate) {
|
|
31
|
+
// This document started the flow and finished it in place — it already has what it needs.
|
|
32
|
+
return LoginOutcome.Passed;
|
|
33
|
+
}
|
|
34
|
+
if (!env.hasOpener) {
|
|
35
|
+
// Authenticated with nowhere to send it. `Cross-Origin-Opener-Policy: same-origin` from the
|
|
36
|
+
// provider severs `window.opener` permanently, so this is not a timing problem to retry.
|
|
37
|
+
return LoginOutcome.Orphaned;
|
|
38
|
+
}
|
|
39
|
+
clearSurrogate();
|
|
40
|
+
// Both windows are the same origin (the surrogate is this application's own login route), so
|
|
41
|
+
// the origin is pinned rather than passed as `*` — the message carries a bearer token.
|
|
42
|
+
window.opener.postMessage({ type: LOGIN_TOKEN_MESSAGE, token }, window.location.origin);
|
|
43
|
+
window.close();
|
|
44
|
+
return LoginOutcome.Handled;
|
|
45
|
+
};
|
|
46
|
+
const plugin = {
|
|
47
|
+
alias: SURROGATE_LOGIN,
|
|
48
|
+
priority: SURROGATE_LOGIN_PRIORITY,
|
|
49
|
+
mode: 'surrogate',
|
|
50
|
+
match: env => env.hasWindow && (env.embedded || env.surrogate),
|
|
51
|
+
enter: () => { markSurrogate(); },
|
|
52
|
+
begin: (ctx, request, env) => {
|
|
53
|
+
// Already one window up — nothing to open, just run the flow.
|
|
54
|
+
if (env.surrogate) {
|
|
55
|
+
window.location.href = request.url;
|
|
56
|
+
return Promise.resolve(LoginOutcome.Redirected);
|
|
57
|
+
}
|
|
58
|
+
// Opened FIRST and synchronously: `window.open` escapes the popup blocker only while the
|
|
59
|
+
// user gesture is still being handled, so nothing may be awaited before this line. That is
|
|
60
|
+
// why this function is not `async`.
|
|
61
|
+
//
|
|
62
|
+
// The window opens on the surrogate route rather than on the dispatcher, so its very first
|
|
63
|
+
// paint is a bare "signing you in" panel instead of the application with its navigation. The
|
|
64
|
+
// dispatcher address travels as `next`, because the provider's callback still lands there and
|
|
65
|
+
// whatever flow parameters the caller's URL carried must survive the hop.
|
|
66
|
+
const path = surrogatePath(ctx, {
|
|
67
|
+
intent: LoginIntent.Login, next: request.url,
|
|
68
|
+
});
|
|
69
|
+
const surrogate = window.open(path ?? request.url, LOGIN_SURROGATE_NAME, LOGIN_SURROGATE_FEATURES);
|
|
70
|
+
if (surrogate == null) {
|
|
71
|
+
return Promise.resolve(LoginOutcome.Failed);
|
|
72
|
+
}
|
|
73
|
+
return awaitSurrogate(surrogate, LOGIN_TOKEN_MESSAGE, async (data) => {
|
|
74
|
+
if (data.token == null || data.token === '') {
|
|
75
|
+
return LoginOutcome.Failed;
|
|
76
|
+
}
|
|
77
|
+
await adoptToken(ctx, data.token);
|
|
78
|
+
// Adopting the token is not the end of the flow — running the caller's continuation is,
|
|
79
|
+
// exactly as the redirect plugin does before it reports `Handled`. Without it the token
|
|
80
|
+
// lands in the auth service and nothing else happens: the framed app keeps rendering its
|
|
81
|
+
// signed-out tree, and the user watches the login window close over a preview that never
|
|
82
|
+
// changes. `Handled` promises the caller there is nothing left to do.
|
|
83
|
+
await request.navigate?.();
|
|
84
|
+
return LoginOutcome.Handled;
|
|
85
|
+
});
|
|
86
|
+
},
|
|
87
|
+
authorize: async (_ctx, url, env) => {
|
|
88
|
+
// The surrogate is top-level, so it redirects like any ordinary tab.
|
|
89
|
+
if (env.surrogate) {
|
|
90
|
+
window.location.href = url;
|
|
91
|
+
return LoginOutcome.Redirected;
|
|
92
|
+
}
|
|
93
|
+
// Framed, and not yet one window up. A redirect from here would land in the frame and be
|
|
94
|
+
// refused, and the window that would fix it cannot be opened without a user gesture — so the
|
|
95
|
+
// caller is told to render a control rather than to navigate.
|
|
96
|
+
return LoginOutcome.Gesture;
|
|
97
|
+
},
|
|
98
|
+
complete: async (_ctx, token, env) => await handBack(token, env),
|
|
99
|
+
// A session that was already here is worth exactly as much as one just issued — to the window
|
|
100
|
+
// that asked for it. Without this the surrogate would render the signed-in application to
|
|
101
|
+
// itself and the framed app would stay signed out, which is the whole reported defect.
|
|
102
|
+
resume: async (_ctx, token, env) => await handBack(token, env),
|
|
103
|
+
logout: (ctx, request, env) => {
|
|
104
|
+
// Already one window up — end the session here and tell the opener.
|
|
105
|
+
if (env.surrogate) {
|
|
106
|
+
return revokeToken(ctx)
|
|
107
|
+
.then(async () => await plugin.logoutComplete(ctx, env));
|
|
108
|
+
}
|
|
109
|
+
const path = surrogatePath(ctx, { intent: LoginIntent.Logout });
|
|
110
|
+
// Opened first and synchronously, for the same reason `begin` does.
|
|
111
|
+
const surrogate = path != null
|
|
112
|
+
? window.open(path, LOGIN_SURROGATE_NAME, LOGIN_SURROGATE_FEATURES)
|
|
113
|
+
: null;
|
|
114
|
+
// The local session goes next, and UNCONDITIONALLY. A blocked window, a severed opener or a
|
|
115
|
+
// user who closes the popup must never leave THIS document signed in: a logout that only
|
|
116
|
+
// half happened is bad, and one that did not happen at all is worse.
|
|
117
|
+
const local = revokeToken(ctx);
|
|
118
|
+
if (surrogate == null) {
|
|
119
|
+
return local.then(async () => {
|
|
120
|
+
await request.navigate?.();
|
|
121
|
+
return LoginOutcome.Failed;
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return local.then(async () => await awaitSurrogate(surrogate, LOGIN_LOGOUT_MESSAGE, async () => {
|
|
125
|
+
await request.navigate?.();
|
|
126
|
+
return LoginOutcome.Handled;
|
|
127
|
+
}));
|
|
128
|
+
},
|
|
129
|
+
logoutComplete: async (_ctx, env) => {
|
|
130
|
+
if (!env.surrogate) {
|
|
131
|
+
return LoginOutcome.Passed;
|
|
132
|
+
}
|
|
133
|
+
if (!env.hasOpener) {
|
|
134
|
+
return LoginOutcome.Orphaned;
|
|
135
|
+
}
|
|
136
|
+
clearSurrogate();
|
|
137
|
+
window.opener.postMessage({ type: LOGIN_LOGOUT_MESSAGE, ok: true }, window.location.origin);
|
|
138
|
+
window.close();
|
|
139
|
+
return LoginOutcome.Handled;
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
return plugin;
|
|
143
|
+
};
|
|
144
|
+
//# sourceMappingURL=surrogate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"surrogate.js","sourceRoot":"","sources":["../../src/login/surrogate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { FC } from 'react';
|
|
2
|
+
import { LoginIntent } from '@owlmeans/client-auth/login';
|
|
3
|
+
/** What the surrogate window is doing, from the point of view of the person watching it. */
|
|
4
|
+
export declare enum SurrogateStage {
|
|
5
|
+
/** Working. No control — there is nothing for the user to do but wait. */
|
|
6
|
+
Working = "working",
|
|
7
|
+
/** Needs a click: the flow cannot continue without a fresh gesture. */
|
|
8
|
+
Gesture = "gesture",
|
|
9
|
+
/** Done here; handing the result back and closing. */
|
|
10
|
+
Handing = "handing",
|
|
11
|
+
/** Acted, but with no channel back to the window that asked. */
|
|
12
|
+
Orphaned = "orphaned",
|
|
13
|
+
/** Ended with nothing. */
|
|
14
|
+
Failed = "failed",
|
|
15
|
+
/** Not a surrogate at all — someone opened this address directly. */
|
|
16
|
+
Standalone = "standalone"
|
|
17
|
+
}
|
|
18
|
+
export interface SurrogateViewProps {
|
|
19
|
+
stage: SurrogateStage;
|
|
20
|
+
intent: LoginIntent;
|
|
21
|
+
onAction?: () => void;
|
|
22
|
+
error?: string;
|
|
23
|
+
translate?: (key: string, defaultValue: string) => string;
|
|
24
|
+
}
|
|
25
|
+
export declare const LoginSurrogateView: FC<SurrogateViewProps>;
|
|
26
|
+
//# sourceMappingURL=view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../src/login/view.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,EAAE,EAAE,MAAM,OAAO,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;AAEzD,4FAA4F;AAC5F,oBAAY,cAAc;IACxB,0EAA0E;IAC1E,OAAO,YAAY;IACnB,uEAAuE;IACvE,OAAO,YAAY;IACnB,sDAAsD;IACtD,OAAO,YAAY;IACnB,gEAAgE;IAChE,QAAQ,aAAa;IACrB,0BAA0B;IAC1B,MAAM,WAAW;IACjB,qEAAqE;IACrE,UAAU,eAAe;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,CAAA;IACrB,MAAM,EAAE,WAAW,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,MAAM,CAAA;CAC1D;AAoDD,eAAO,MAAM,kBAAkB,EAAE,EAAE,CAAC,kBAAkB,CAgBrD,CAAA"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { LoginIntent } from '@owlmeans/client-auth/login';
|
|
3
|
+
/** What the surrogate window is doing, from the point of view of the person watching it. */
|
|
4
|
+
export var SurrogateStage;
|
|
5
|
+
(function (SurrogateStage) {
|
|
6
|
+
/** Working. No control — there is nothing for the user to do but wait. */
|
|
7
|
+
SurrogateStage["Working"] = "working";
|
|
8
|
+
/** Needs a click: the flow cannot continue without a fresh gesture. */
|
|
9
|
+
SurrogateStage["Gesture"] = "gesture";
|
|
10
|
+
/** Done here; handing the result back and closing. */
|
|
11
|
+
SurrogateStage["Handing"] = "handing";
|
|
12
|
+
/** Acted, but with no channel back to the window that asked. */
|
|
13
|
+
SurrogateStage["Orphaned"] = "orphaned";
|
|
14
|
+
/** Ended with nothing. */
|
|
15
|
+
SurrogateStage["Failed"] = "failed";
|
|
16
|
+
/** Not a surrogate at all — someone opened this address directly. */
|
|
17
|
+
SurrogateStage["Standalone"] = "standalone";
|
|
18
|
+
})(SurrogateStage || (SurrogateStage = {}));
|
|
19
|
+
/**
|
|
20
|
+
* The whole of what a login window shows.
|
|
21
|
+
*
|
|
22
|
+
* Plain elements and inline styles on purpose. This renders in a popup opened by a `web-panel` app,
|
|
23
|
+
* a `mui-panel` app and a generated Tailwind app alike, and none of their stylesheets is loaded
|
|
24
|
+
* here — a class name would simply do nothing. It is also the reason this component carries no
|
|
25
|
+
* dependency on a UI family at all.
|
|
26
|
+
*/
|
|
27
|
+
const box = {
|
|
28
|
+
maxWidth: '22rem', margin: '15vh auto', padding: '1.5rem', textAlign: 'center',
|
|
29
|
+
fontFamily: 'system-ui, sans-serif', lineHeight: 1.5,
|
|
30
|
+
};
|
|
31
|
+
const action = {
|
|
32
|
+
marginTop: '1rem', padding: '.625rem 1.25rem', fontSize: '1rem',
|
|
33
|
+
cursor: 'pointer', borderRadius: '.375rem', border: '1px solid currentColor',
|
|
34
|
+
};
|
|
35
|
+
const COPY = {
|
|
36
|
+
[SurrogateStage.Working]: { key: 'working', en: 'Signing you in…' },
|
|
37
|
+
[SurrogateStage.Gesture]: {
|
|
38
|
+
key: 'gesture.title', en: 'Continue to sign in.', action: ['gesture.action', 'Sign in'],
|
|
39
|
+
},
|
|
40
|
+
[SurrogateStage.Handing]: { key: 'handing', en: 'Done. Returning to the application…' },
|
|
41
|
+
[SurrogateStage.Orphaned]: {
|
|
42
|
+
key: 'orphaned', en: 'Signed in. You can close this window and continue in the application.',
|
|
43
|
+
action: ['close', 'Close'],
|
|
44
|
+
},
|
|
45
|
+
[SurrogateStage.Failed]: {
|
|
46
|
+
key: 'failed', en: 'That did not complete. You can close this window and try again.',
|
|
47
|
+
action: ['close', 'Close'],
|
|
48
|
+
},
|
|
49
|
+
[SurrogateStage.Standalone]: {
|
|
50
|
+
key: 'standalone.title', en: 'This page is used to sign in from another window.',
|
|
51
|
+
action: ['standalone.action', 'Open the application'],
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
const LOGOUT_COPY = {
|
|
55
|
+
[SurrogateStage.Working]: { key: 'working', en: 'Signing you out…' },
|
|
56
|
+
[SurrogateStage.Gesture]: { key: 'gesture.title', en: 'Continue to sign out.' },
|
|
57
|
+
[SurrogateStage.Handing]: { key: 'handing', en: 'Signed out. Returning to the application…' },
|
|
58
|
+
[SurrogateStage.Orphaned]: {
|
|
59
|
+
key: 'orphaned', en: 'Signed out. You can close this window.',
|
|
60
|
+
},
|
|
61
|
+
[SurrogateStage.Failed]: {
|
|
62
|
+
key: 'failed', en: 'Sign-out did not complete here. You can close this window.',
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
export const LoginSurrogateView = ({ stage, intent, onAction, error, translate }) => {
|
|
66
|
+
const t = translate ?? ((_key, defaultValue) => defaultValue);
|
|
67
|
+
const scope = intent === LoginIntent.Logout ? 'logout' : 'login';
|
|
68
|
+
const base = COPY[stage];
|
|
69
|
+
const copy = (intent === LoginIntent.Logout ? LOGOUT_COPY[stage] : undefined) ?? base;
|
|
70
|
+
return _jsxs("div", { style: box, "data-surrogate-stage": stage, "data-surrogate-intent": intent, children: [_jsx("p", { children: t(`surrogate.${scope}.${copy.key}`, copy.en) }), error != null && error !== '' &&
|
|
71
|
+
_jsx("p", { style: { color: '#b00', fontSize: '.875rem' }, role: "alert", children: error }), base.action != null && onAction != null && _jsx("button", { type: "button", style: action, onClick: onAction, children: t(`surrogate.${scope}.${base.action[0]}`, base.action[1]) })] });
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.js","sourceRoot":"","sources":["../../src/login/view.tsx"],"names":[],"mappings":"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"}
|
package/build/main.d.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
import type { AppConfig, AppContext, RenderOptions } from './types.js';
|
|
3
3
|
export declare const render: (node: ReactNode, opts?: RenderOptions) => void;
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Mount the application.
|
|
6
|
+
*
|
|
7
|
+
* `children` are rendered inside the context provider and BEFORE the router, which makes them the
|
|
8
|
+
* app's global overlay slot: a consent dialog, a toast surface, anything that must exist on every
|
|
9
|
+
* route and outlive navigation. A component mounted inside a route instead is torn down and
|
|
10
|
+
* rebuilt on every navigation, which for a dialog means it closes itself.
|
|
11
|
+
*/
|
|
12
|
+
export declare const renderApp: <C extends AppConfig, T extends AppContext<C>>(context: T, opts?: RenderOptions, children?: ReactNode) => void;
|
|
5
13
|
//# sourceMappingURL=main.d.ts.map
|
package/build/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAGtE,eAAO,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAGtE,eAAO,MAAM,MAAM,GAAI,MAAM,SAAS,EAAE,OAAO,aAAa,SAkB3D,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,EACpE,SAAS,CAAC,EAAE,OAAO,aAAa,EAAE,WAAW,SAAS,SACQ,CAAA"}
|
package/build/main.js
CHANGED
|
@@ -21,5 +21,13 @@ export const render = (node, opts) => {
|
|
|
21
21
|
};
|
|
22
22
|
opts?.onReady ?? true ? window.addEventListener('DOMContentLoaded', _callback) : _callback();
|
|
23
23
|
};
|
|
24
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Mount the application.
|
|
26
|
+
*
|
|
27
|
+
* `children` are rendered inside the context provider and BEFORE the router, which makes them the
|
|
28
|
+
* app's global overlay slot: a consent dialog, a toast surface, anything that must exist on every
|
|
29
|
+
* route and outlive navigation. A component mounted inside a route instead is torn down and
|
|
30
|
+
* rebuilt on every navigation, which for a dialog means it closes itself.
|
|
31
|
+
*/
|
|
32
|
+
export const renderApp = (context, opts, children) => render(_jsx(WebApp, { context: context, children: children }), opts);
|
|
25
33
|
//# sourceMappingURL=main.js.map
|
package/build/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAE9C,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,IAAe,EAAE,IAAoB,EAAE,EAAE;IAC9D,MAAM,SAAS,GAAG,GAAG,EAAE;QACrB,MAAM,GAAG,GAAG,IAAI,EAAE,KAAK,IAAI,YAAY,CAAA;QACvC,MAAM,IAAI,GAAG,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,CAAA;QACzC,IAAI,IAAI,EAAE,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,KAAK,CAAC,uBAAuB,GAAG,EAAE,CAAC,CAAA;QAC7C,CAAC;QACD,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,mCAAmC,GAAG,EAAE,CAAC,CAAA;QAC3D,CAAC;QACD,IAAI,IAAI,EAAE,OAAO,KAAK,IAAI,EAAE,CAAC;YAC3B,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QACzB,CAAC;aAAM,CAAC;YACN,UAAU,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAC/B,CAAC;IACH,CAAC,CAAA;IAED,IAAI,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAA;AAC9F,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAE9C,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,IAAe,EAAE,IAAoB,EAAE,EAAE;IAC9D,MAAM,SAAS,GAAG,GAAG,EAAE;QACrB,MAAM,GAAG,GAAG,IAAI,EAAE,KAAK,IAAI,YAAY,CAAA;QACvC,MAAM,IAAI,GAAG,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,CAAA;QACzC,IAAI,IAAI,EAAE,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,KAAK,CAAC,uBAAuB,GAAG,EAAE,CAAC,CAAA;QAC7C,CAAC;QACD,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,mCAAmC,GAAG,EAAE,CAAC,CAAA;QAC3D,CAAC;QACD,IAAI,IAAI,EAAE,OAAO,KAAK,IAAI,EAAE,CAAC;YAC3B,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QACzB,CAAC;aAAM,CAAC;YACN,UAAU,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAC/B,CAAC;IACH,CAAC,CAAA;IAED,IAAI,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAA;AAC9F,CAAC,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CACvB,OAAU,EAAE,IAAoB,EAAE,QAAoB,EACtD,EAAE,CAAC,MAAM,CAAC,KAAC,MAAM,IAAC,OAAO,EAAE,OAAO,YAAG,QAAQ,GAAU,EAAE,IAAI,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAQnD,eAAO,MAAM,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAQnD,eAAO,MAAM,gBAAgB,EAAE,UAuC9B,CAAA"}
|
package/build/middleware.js
CHANGED
|
@@ -7,18 +7,19 @@ export const logoutMiddleware = {
|
|
|
7
7
|
stage: MiddlewareStage.Loading,
|
|
8
8
|
apply: async (context) => {
|
|
9
9
|
context.entrypoints().forEach(module => {
|
|
10
|
-
if (module.route.route.type === AppType.Backend && module.
|
|
10
|
+
if (module.route.route.type === AppType.Backend && module.invoke != null) {
|
|
11
11
|
const guards = module.getGuards();
|
|
12
12
|
if (guards.length > 0) {
|
|
13
13
|
if (module._auth_web_middleware_applied === true) {
|
|
14
14
|
return;
|
|
15
15
|
}
|
|
16
16
|
module._auth_web_middleware_applied = true;
|
|
17
|
-
//
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
// Wrapping `invoke` covers `call` too: `call` reads `invoke` off the entrypoint at the
|
|
18
|
+
// moment it runs, so a rejected session is caught whichever verb the caller used.
|
|
19
|
+
const invoke = module.invoke;
|
|
20
|
+
module.invoke = (async (req) => {
|
|
20
21
|
try {
|
|
21
|
-
return await
|
|
22
|
+
return await invoke(req);
|
|
22
23
|
}
|
|
23
24
|
catch (e) {
|
|
24
25
|
if (e instanceof Error) {
|
|
@@ -35,7 +36,7 @@ export const logoutMiddleware = {
|
|
|
35
36
|
}
|
|
36
37
|
throw e;
|
|
37
38
|
}
|
|
38
|
-
};
|
|
39
|
+
});
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
42
|
});
|
package/build/middleware.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAE5E,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAGrD,MAAM,CAAC,MAAM,gBAAgB,GAAe;IAC1C,IAAI,EAAE,cAAc,CAAC,OAAO;IAC5B,KAAK,EAAE,eAAe,CAAC,OAAO;IAC9B,KAAK,EAAE,KAAK,EAAC,OAAO,EAAC,EAAE;QACrB,OAAO,CAAC,WAAW,EAAU,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YAC7C,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAE5E,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAGrD,MAAM,CAAC,MAAM,gBAAgB,GAAe;IAC1C,IAAI,EAAE,cAAc,CAAC,OAAO;IAC5B,KAAK,EAAE,eAAe,CAAC,OAAO;IAC9B,KAAK,EAAE,KAAK,EAAC,OAAO,EAAC,EAAE;QACrB,OAAO,CAAC,WAAW,EAAU,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YAC7C,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;gBACzE,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CAAA;gBACjC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACtB,IAAI,MAAM,CAAC,4BAA4B,KAAK,IAAI,EAAE,CAAC;wBACjD,OAAM;oBACR,CAAC;oBACD,MAAM,CAAC,4BAA4B,GAAG,IAAI,CAAA;oBAC1C,uFAAuF;oBACvF,kFAAkF;oBAClF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;oBAC5B,MAAM,CAAC,MAAM,GAAG,CAAC,KAAK,EAAC,GAAG,EAAC,EAAE;wBAC3B,IAAI,CAAC;4BACH,OAAO,MAAM,MAAM,CAAC,GAAG,CAAC,CAAA;wBAC1B,CAAC;wBAAC,OAAO,CAAC,EAAE,CAAC;4BACX,IAAI,CAAC,YAAY,KAAK,EAAE,CAAC;gCACvB,MAAM,GAAG,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;gCACpC,IAAI,GAAG,YAAY,WAAW,EAAE,CAAC;oCAC/B,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;wCACrC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;4CAClC,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAc,aAAa,CAAC,CAAA;4CACxD,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;4CAC5B,MAAM,GAAG,CAAA;wCACX,CAAC;oCACH,CAAC;gCACH,CAAC;4BACH,CAAC;4BACD,MAAM,CAAC,CAAA;wBACT,CAAC;oBACH,CAAC,CAAyB,CAAA;gBAE5B,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;CACF,CAAA"}
|
package/build/service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAE9D,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAI3E,eAAO,MAAM,kBAAkB,
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAE9D,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAI3E,eAAO,MAAM,kBAAkB,GAAI,QAAO,MAAsB,KAAG,WAclE,CAAA;AAED,eAAO,MAAM,oBAAoB,GAAI,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,aAAa,CAAC,CAAC,CAAC,EACrF,KAAK,CAAC,EAAE,QAAO,MAAsB,KACpC,CAAC,GAAG,iBAaN,CAAA"}
|
package/build/service.js
CHANGED
|
@@ -9,7 +9,7 @@ export const makeAuthWebService = (alias = DEFAULT_ALIAS) => {
|
|
|
9
9
|
await update(token);
|
|
10
10
|
if (token == null) {
|
|
11
11
|
const module = service.assertCtx().entrypoint(DISPATCHER);
|
|
12
|
-
const
|
|
12
|
+
const url = await module.url();
|
|
13
13
|
document.location.href = url;
|
|
14
14
|
}
|
|
15
15
|
};
|
package/build/service.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE3C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAEtD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAGtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAElD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE3C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAEtD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAGtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAElD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,QAAgB,aAAa,EAAe,EAAE;IAC/E,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,CAAA;IAEtC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;IAC7B,OAAO,CAAC,MAAM,GAAG,KAAK,EAAC,KAAK,EAAC,EAAE;QAC7B,MAAM,MAAM,CAAC,KAAK,CAAC,CAAA;QACnB,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;YAClB,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,UAAU,CAA2B,UAAU,CAAC,CAAA;YACnF,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,EAAE,CAAA;YAC9B,QAAQ,CAAC,QAAQ,CAAC,IAAI,GAAG,GAAG,CAAA;QAC9B,CAAC;IACH,CAAC,CAAA;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,GAAM,EAAE,QAAgB,aAAa,EACd,EAAE;IACzB,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAA;IAEzC,MAAM,OAAO,GAAG,GAA4B,CAAA;IAE5C,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAA;IAEhC,OAAO,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAA;IAC1C,OAAO,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAA;IAE5C,OAAO,CAAC,IAAI,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAE/C,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA"}
|
package/build/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AuthServiceAppend } from '@owlmeans/client-auth';
|
|
2
|
+
import type { LoginServiceAppend } from '@owlmeans/client-auth/login';
|
|
2
3
|
import type { ClientConfig } from '@owlmeans/client-context';
|
|
3
4
|
import type { ClientContext } from '@owlmeans/client';
|
|
4
5
|
export interface RenderOptions {
|
|
@@ -9,6 +10,6 @@ export interface RenderOptions {
|
|
|
9
10
|
}
|
|
10
11
|
export interface AppConfig extends ClientConfig {
|
|
11
12
|
}
|
|
12
|
-
export interface AppContext<C extends AppConfig = AppConfig> extends ClientContext<C>, AuthServiceAppend {
|
|
13
|
+
export interface AppContext<C extends AppConfig = AppConfig> extends ClientContext<C>, AuthServiceAppend, LoginServiceAppend {
|
|
13
14
|
}
|
|
14
15
|
//# sourceMappingURL=types.d.ts.map
|
package/build/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAErD,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,SAAU,SAAQ,YAAY;CAC9C;AAED,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC,EACnF,iBAAiB;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAErD,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,SAAU,SAAQ,YAAY;CAC9C;AAED,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC,EACnF,iBAAiB,EAAE,kBAAkB;CACtC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/web-client",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.21",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -21,22 +21,22 @@
|
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@owlmeans/auth": "^0.1.18-rc.
|
|
25
|
-
"@owlmeans/auth-common": "^0.1.18-rc.
|
|
26
|
-
"@owlmeans/client": "^0.1.18-rc.
|
|
27
|
-
"@owlmeans/client-auth": "^0.1.18-rc.
|
|
28
|
-
"@owlmeans/client-context": "^0.1.18-rc.
|
|
29
|
-
"@owlmeans/client-i18n": "^0.1.18-rc.
|
|
30
|
-
"@owlmeans/client-entrypoint": "^0.1.18-rc.
|
|
31
|
-
"@owlmeans/client-resource": "^0.1.18-rc.
|
|
32
|
-
"@owlmeans/client-route": "^0.1.18-rc.
|
|
33
|
-
"@owlmeans/config": "^0.1.18-rc.
|
|
34
|
-
"@owlmeans/context": "^0.1.18-rc.
|
|
35
|
-
"@owlmeans/error": "^0.1.18-rc.
|
|
36
|
-
"@owlmeans/i18n": "^0.1.18-rc.
|
|
37
|
-
"@owlmeans/route": "^0.1.18-rc.
|
|
38
|
-
"@owlmeans/web-db": "^0.1.18-rc.
|
|
39
|
-
"@owlmeans/web-router": "^0.1.18-rc.
|
|
24
|
+
"@owlmeans/auth": "^0.1.18-rc.8",
|
|
25
|
+
"@owlmeans/auth-common": "^0.1.18-rc.11",
|
|
26
|
+
"@owlmeans/client": "^0.1.18-rc.13",
|
|
27
|
+
"@owlmeans/client-auth": "^0.1.18-rc.17",
|
|
28
|
+
"@owlmeans/client-context": "^0.1.18-rc.11",
|
|
29
|
+
"@owlmeans/client-i18n": "^0.1.18-rc.12",
|
|
30
|
+
"@owlmeans/client-entrypoint": "^0.1.18-rc.11",
|
|
31
|
+
"@owlmeans/client-resource": "^0.1.18-rc.11",
|
|
32
|
+
"@owlmeans/client-route": "^0.1.18-rc.11",
|
|
33
|
+
"@owlmeans/config": "^0.1.18-rc.10",
|
|
34
|
+
"@owlmeans/context": "^0.1.18-rc.7",
|
|
35
|
+
"@owlmeans/error": "^0.1.18-rc.7",
|
|
36
|
+
"@owlmeans/i18n": "^0.1.18-rc.7",
|
|
37
|
+
"@owlmeans/route": "^0.1.18-rc.7",
|
|
38
|
+
"@owlmeans/web-db": "^0.1.18-rc.12",
|
|
39
|
+
"@owlmeans/web-router": "^0.1.18-rc.12",
|
|
40
40
|
"react-dropzone": "^14.3.5"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
@@ -1,16 +1,33 @@
|
|
|
1
1
|
import { DispatcherHOC } from '@owlmeans/client-auth'
|
|
2
|
-
import { useEffect } from 'react'
|
|
2
|
+
import { useEffect, useState } from 'react'
|
|
3
3
|
import { useI18nLib } from '@owlmeans/client-i18n'
|
|
4
4
|
import { AUTH_QUERY } from '@owlmeans/auth'
|
|
5
|
+
import {
|
|
6
|
+
FallbackLoginScreen, LoginIntent, LoginOutcome, ResumeAction, resumeAction,
|
|
7
|
+
} from '@owlmeans/client-auth/login'
|
|
8
|
+
import { LoginSurrogateView, SurrogateStage } from '../../login/view.js'
|
|
5
9
|
import { useContext } from '../../context.js'
|
|
6
10
|
|
|
7
|
-
export const Dispatcher = DispatcherHOC(({ provideToken }) => {
|
|
11
|
+
export const Dispatcher = DispatcherHOC(({ provideToken, navigate }) => {
|
|
8
12
|
const context = useContext()
|
|
9
13
|
const [query] = context.router().useSearchParams()
|
|
10
14
|
|
|
11
15
|
const t = useI18nLib('auth', 'dispatcher')
|
|
16
|
+
const tAuth = useI18nLib('auth')
|
|
17
|
+
|
|
18
|
+
// Read in the component body, not in the effect: `window.name` is set by `window.open` before
|
|
19
|
+
// this document loads and `sessionStorage` carries the marker across the provider round trip, so
|
|
20
|
+
// the answer is already correct at first paint — and a first paint that showed the application
|
|
21
|
+
// before an effect corrected it is the defect this exists to prevent.
|
|
22
|
+
const [env] = useState(() => context.login().env())
|
|
23
|
+
const [outcome, setOutcome] = useState<LoginOutcome | null>(null)
|
|
24
|
+
// Nothing to return from and nobody signed in: offer the choice rather than starting a flow.
|
|
25
|
+
const [choose, setChoose] = useState(false)
|
|
12
26
|
|
|
13
27
|
useEffect(() => {
|
|
28
|
+
// First statement of the effect on purpose: everything below can navigate this window away.
|
|
29
|
+
context.login().enter()
|
|
30
|
+
|
|
14
31
|
const token = query.get(AUTH_QUERY)
|
|
15
32
|
if (token != null) {
|
|
16
33
|
const params: Record<string, string> = {}
|
|
@@ -21,15 +38,62 @@ export const Dispatcher = DispatcherHOC(({ provideToken }) => {
|
|
|
21
38
|
})
|
|
22
39
|
|
|
23
40
|
provideToken({ token }, params)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (authzToken == null) {
|
|
27
|
-
provideToken({ token: '' }, undefined)
|
|
28
|
-
}
|
|
29
|
-
})
|
|
41
|
+
|
|
42
|
+
return
|
|
30
43
|
}
|
|
44
|
+
|
|
45
|
+
void context.auth().authenticated().then(async authzToken => {
|
|
46
|
+
if (authzToken == null || authzToken === '') {
|
|
47
|
+
setChoose(true)
|
|
48
|
+
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
// A session already exists in THIS document. Whether it is useful here, or belongs to the
|
|
52
|
+
// window that opened this one, is the plugin's call — the dispatcher reads no environment.
|
|
53
|
+
const settled = await context.login().resume(authzToken)
|
|
54
|
+
switch (resumeAction(settled)) {
|
|
55
|
+
case ResumeAction.Stop:
|
|
56
|
+
return
|
|
57
|
+
case ResumeAction.Render:
|
|
58
|
+
setOutcome(settled)
|
|
59
|
+
|
|
60
|
+
return
|
|
61
|
+
default:
|
|
62
|
+
await navigate()
|
|
63
|
+
}
|
|
64
|
+
})
|
|
31
65
|
}, [])
|
|
32
66
|
|
|
67
|
+
// A surrogate window never renders the application, whatever else is true. Checked ahead of
|
|
68
|
+
// every other return for exactly that reason.
|
|
69
|
+
//
|
|
70
|
+
// `choose` is the one state this must NOT mask, and it is not an exception to the rule: the
|
|
71
|
+
// login chooser is not the application. A login window with nothing to return from and nobody
|
|
72
|
+
// signed in has exactly one thing left that can move it forward, and that is asking which
|
|
73
|
+
// provider. The surrogate URL normally carries `?method=` so the question is already settled,
|
|
74
|
+
// but a window opened from a bare "Log in" — the framed application's own header button — has no
|
|
75
|
+
// method to send. Returning the "working" panel there left the popup on "Signing you in…"
|
|
76
|
+
// permanently, because nothing was ever going to start.
|
|
77
|
+
if (env.surrogate && !choose) {
|
|
78
|
+
return <LoginSurrogateView
|
|
79
|
+
intent={LoginIntent.Login}
|
|
80
|
+
stage={
|
|
81
|
+
outcome === LoginOutcome.Orphaned ? SurrogateStage.Orphaned
|
|
82
|
+
: outcome === LoginOutcome.Failed ? SurrogateStage.Failed
|
|
83
|
+
: outcome === LoginOutcome.Gesture ? SurrogateStage.Gesture
|
|
84
|
+
: SurrogateStage.Working
|
|
85
|
+
}
|
|
86
|
+
onAction={() => window.close()}
|
|
87
|
+
translate={(key, defaultValue) => tAuth(key, { defaultValue })}
|
|
88
|
+
/>
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (choose) {
|
|
92
|
+
const Screen = context.login().screen() ?? FallbackLoginScreen
|
|
93
|
+
|
|
94
|
+
return <Screen translate={(key, defaultValue) => tAuth(key, { defaultValue })} />
|
|
95
|
+
}
|
|
96
|
+
|
|
33
97
|
return query.has(AUTH_QUERY) ? <div style={{
|
|
34
98
|
width: '100%', // Makes the div occupy the full width
|
|
35
99
|
display: 'flex', // Enables flexbox layout
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { EntrypointContextParams } from "@owlmeans/client"
|
|
2
2
|
import type { DispatcherProps } from "@owlmeans/client-auth"
|
|
3
3
|
import type { PropsWithChildren } from "react"
|
|
4
4
|
|
|
5
|
-
export interface ParametrisedProps extends PropsWithChildren<
|
|
5
|
+
export interface ParametrisedProps extends PropsWithChildren<EntrypointContextParams & DispatcherProps> {
|
|
6
6
|
}
|
package/src/context.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { useContext as useCtx } from '@owlmeans/client'
|
|
|
8
8
|
import { extractPrimaryHost } from './helper.js'
|
|
9
9
|
import { appendWebAuthService } from './service.js'
|
|
10
10
|
import { appendWebRouter } from '@owlmeans/web-router'
|
|
11
|
+
import { appendWebLogin } from './login/service.js'
|
|
11
12
|
|
|
12
13
|
export const makeContext = <C extends AppConfig = AppConfig, T extends AppContext<C> = AppContext<C>>(
|
|
13
14
|
cfg: C
|
|
@@ -19,8 +20,7 @@ export const makeContext = <C extends AppConfig = AppConfig, T extends AppContex
|
|
|
19
20
|
appendWebDbService<C, T>(context)
|
|
20
21
|
appendClientResource<C, T>(context, AUTH_RESOURCE)
|
|
21
22
|
appendWebRouter<C, T>(context)
|
|
22
|
-
|
|
23
|
-
context.makeContext = makeContext as typeof context.makeContext
|
|
23
|
+
appendWebLogin<C, T>(context)
|
|
24
24
|
|
|
25
25
|
return context
|
|
26
26
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DISPATCHER, DISPATCHER_SURROGATE } from '@owlmeans/auth'
|
|
2
|
+
import { entrypoints as list } from '@owlmeans/client-auth'
|
|
3
|
+
import { elevate } from '@owlmeans/client-entrypoint'
|
|
4
|
+
import { handler } from '@owlmeans/client'
|
|
5
|
+
import { Dispatcher } from './components/dispatcher/component.js'
|
|
6
|
+
import { SurrogateScreen } from './login/screen.js'
|
|
7
|
+
|
|
8
|
+
elevate(list, DISPATCHER, handler(Dispatcher))
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Elevated here rather than in a relying-party package on purpose.
|
|
12
|
+
*
|
|
13
|
+
* The surrogate mechanic is not OIDC-specific — it is "run the login route one window up and hand
|
|
14
|
+
* the result back" — and every web application already spreads this list. Putting the screen here
|
|
15
|
+
* means `web-panel`, `mui-panel` and every generated target gain a working login window with no
|
|
16
|
+
* edit of their own, which is the only way an application that is already deployed can get it.
|
|
17
|
+
*/
|
|
18
|
+
elevate(list, DISPATCHER_SURROGATE, handler(SurrogateScreen))
|
|
19
|
+
|
|
20
|
+
export const entrypoints = list
|
package/src/exports.ts
CHANGED
|
@@ -5,5 +5,6 @@ export { service } from '@owlmeans/config'
|
|
|
5
5
|
export { AppType, HOME, ROOT, BASE, GUEST } from '@owlmeans/context'
|
|
6
6
|
export { entrypoint, elevate, provideRequest, stab } from '@owlmeans/client-entrypoint'
|
|
7
7
|
export { route, frontend } from '@owlmeans/route'
|
|
8
|
+
export type { ClientEntrypoint } from '@owlmeans/client-entrypoint'
|
|
8
9
|
export type { ClientEntrypoint as Module } from '@owlmeans/client-entrypoint'
|
|
9
10
|
export type { ClientRoute as Route } from '@owlmeans/client-route'
|