@aglyn/aglyn 1.0.0-beta.263 → 1.0.0-beta.264

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aglyn/aglyn",
3
- "version": "1.0.0-beta.263",
3
+ "version": "1.0.0-beta.264",
4
4
  "license": "Apache-2.0",
5
5
  "homepage": "https://aglyn.com",
6
6
  "repository": {
@@ -37,16 +37,16 @@
37
37
  "./package.json": "./package.json"
38
38
  },
39
39
  "dependencies": {
40
- "@aglyn/shared-data-enums": "1.0.0-beta.263",
41
- "@aglyn/shared-data-mdi": "1.0.0-beta.263",
42
- "@aglyn/shared-data-types": "1.0.0-beta.263",
43
- "@aglyn/shared-util-email": "1.0.0-beta.263",
44
- "@aglyn/shared-util-first-touch": "1.0.0-beta.263",
45
- "@aglyn/shared-util-http": "1.0.0-beta.263",
46
- "@aglyn/shared-util-logger": "1.0.0-beta.263",
47
- "@aglyn/shared-util-timestamp": "1.0.0-beta.263",
48
- "@aglyn/shared-util-tools": "1.0.0-beta.263",
49
- "@aglyn/shared-util-vendor": "1.0.0-beta.263",
40
+ "@aglyn/shared-data-enums": "1.0.0-beta.264",
41
+ "@aglyn/shared-data-mdi": "1.0.0-beta.264",
42
+ "@aglyn/shared-data-types": "1.0.0-beta.264",
43
+ "@aglyn/shared-util-email": "1.0.0-beta.264",
44
+ "@aglyn/shared-util-first-touch": "1.0.0-beta.264",
45
+ "@aglyn/shared-util-http": "1.0.0-beta.264",
46
+ "@aglyn/shared-util-logger": "1.0.0-beta.264",
47
+ "@aglyn/shared-util-timestamp": "1.0.0-beta.264",
48
+ "@aglyn/shared-util-tools": "1.0.0-beta.264",
49
+ "@aglyn/shared-util-vendor": "1.0.0-beta.264",
50
50
  "@data-driven-forms/react-form-renderer": "^4.2.0",
51
51
  "@msgpack/msgpack": "^3.1.3",
52
52
  "@types/unist": "^3.0.3",
@@ -0,0 +1,63 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * Whether a page is running inside the native apps' web view (AGL-3894).
19
+ *
20
+ * The Aglyn apps (iPhone, iPad, Mac, Android, Windows) open the Besigner in
21
+ * an in-app web view. Inside it the app owns what a browser tab would offer:
22
+ * its own push notifications, its own Done button, its own window title. The
23
+ * page uses this to leave those web-only extras out.
24
+ *
25
+ * Two signals, either one enough:
26
+ *
27
+ * - **The user-agent marker.** Every app's web view appends
28
+ * `AglynApp/<version> (<platform>)` to its user agent (WKWebView's
29
+ * `applicationNameForUserAgent`, Android's `userAgentString`, WebView2's
30
+ * `UserAgent`). It is there from the first request, whichever page the
31
+ * view opens first, so it holds even for a build that predates the entry
32
+ * page below.
33
+ * - **The entry page's session mark.** `/auth/besigner` marks the tab when
34
+ * the app opens the Besigner through it (AGL-3850). Session storage lives
35
+ * exactly as long as the web view and never reaches a browser tab.
36
+ *
37
+ * PRESENTATION ONLY. A user agent is whatever the client says it is, so this
38
+ * decides what the page shows (a prompt, a back arrow, a title) and never
39
+ * what anyone may do: no auth, entitlement or security decision reads it.
40
+ */
41
+ /** The product token every app's web view adds to its user agent. */
42
+ export declare const NATIVE_APP_USER_AGENT_PRODUCT = "AglynApp";
43
+ /**
44
+ * The marker the apps append, for the native code's specs and for anyone
45
+ * reading this file to know the exact shape: `AglynApp/1.4.0 (ios)`.
46
+ */
47
+ export declare function nativeAppUserAgentMarker(version: string, platform: string): string;
48
+ /** Whether a user-agent string carries the apps' marker. */
49
+ export declare function userAgentNamesNativeApp(userAgent: string | null | undefined): boolean;
50
+ /**
51
+ * Remember, for this tab, that it is the native apps' web view. Called by the
52
+ * Besigner entry page the apps open first.
53
+ */
54
+ export declare function markNativeAppWebView(): void;
55
+ /** Whether this page is inside the native apps' web view. */
56
+ export declare function isNativeAppWebView(): boolean;
57
+ /**
58
+ * `isNativeAppWebView()` for a render. The server cannot tell, so it renders
59
+ * the browser's page and hydration agrees with it; the client then renders
60
+ * again with the answer. Neither signal changes while a page is open, so
61
+ * there is nothing to subscribe to.
62
+ */
63
+ export declare function useIsNativeAppWebView(): boolean;
@@ -0,0 +1,83 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ import { useSyncExternalStore } from "react";
17
+ /**
18
+ * Whether a page is running inside the native apps' web view (AGL-3894).
19
+ *
20
+ * The Aglyn apps (iPhone, iPad, Mac, Android, Windows) open the Besigner in
21
+ * an in-app web view. Inside it the app owns what a browser tab would offer:
22
+ * its own push notifications, its own Done button, its own window title. The
23
+ * page uses this to leave those web-only extras out.
24
+ *
25
+ * Two signals, either one enough:
26
+ *
27
+ * - **The user-agent marker.** Every app's web view appends
28
+ * `AglynApp/<version> (<platform>)` to its user agent (WKWebView's
29
+ * `applicationNameForUserAgent`, Android's `userAgentString`, WebView2's
30
+ * `UserAgent`). It is there from the first request, whichever page the
31
+ * view opens first, so it holds even for a build that predates the entry
32
+ * page below.
33
+ * - **The entry page's session mark.** `/auth/besigner` marks the tab when
34
+ * the app opens the Besigner through it (AGL-3850). Session storage lives
35
+ * exactly as long as the web view and never reaches a browser tab.
36
+ *
37
+ * PRESENTATION ONLY. A user agent is whatever the client says it is, so this
38
+ * decides what the page shows (a prompt, a back arrow, a title) and never
39
+ * what anyone may do: no auth, entitlement or security decision reads it.
40
+ */ /** The product token every app's web view adds to its user agent. */ export const NATIVE_APP_USER_AGENT_PRODUCT = 'AglynApp';
41
+ /** Set by the Besigner entry page for the life of the web view's tab. */ const NATIVE_APP_WEB_VIEW_KEY = 'aglyn:native-app-web-view';
42
+ /** `AglynApp/<version>` as its own token: not inside a longer product name. */ const USER_AGENT_MARKER = new RegExp(`(?:^|[\\s(;])${NATIVE_APP_USER_AGENT_PRODUCT}/[^\\s/]+`);
43
+ /**
44
+ * The marker the apps append, for the native code's specs and for anyone
45
+ * reading this file to know the exact shape: `AglynApp/1.4.0 (ios)`.
46
+ */ export function nativeAppUserAgentMarker(version, platform) {
47
+ return `${NATIVE_APP_USER_AGENT_PRODUCT}/${version || '0'} (${platform})`;
48
+ }
49
+ /** Whether a user-agent string carries the apps' marker. */ export function userAgentNamesNativeApp(userAgent) {
50
+ return typeof userAgent === 'string' && USER_AGENT_MARKER.test(userAgent);
51
+ }
52
+ /**
53
+ * Remember, for this tab, that it is the native apps' web view. Called by the
54
+ * Besigner entry page the apps open first.
55
+ */ export function markNativeAppWebView() {
56
+ try {
57
+ window.sessionStorage.setItem(NATIVE_APP_WEB_VIEW_KEY, '1');
58
+ } catch (unused) {
59
+ // Storage refused: the user-agent marker still answers.
60
+ }
61
+ }
62
+ /** Whether this page is inside the native apps' web view. */ export function isNativeAppWebView() {
63
+ var _window_navigator;
64
+ if (typeof window === 'undefined') return false;
65
+ if (userAgentNamesNativeApp((_window_navigator = window.navigator) == null ? void 0 : _window_navigator.userAgent)) return true;
66
+ try {
67
+ return window.sessionStorage.getItem(NATIVE_APP_WEB_VIEW_KEY) === '1';
68
+ } catch (unused) {
69
+ return false;
70
+ }
71
+ }
72
+ const subscribeNever = ()=>()=>undefined;
73
+ const onServer = ()=>false;
74
+ /**
75
+ * `isNativeAppWebView()` for a render. The server cannot tell, so it renders
76
+ * the browser's page and hydration agrees with it; the client then renders
77
+ * again with the answer. Neither signal changes while a page is open, so
78
+ * there is nothing to subscribe to.
79
+ */ export function useIsNativeAppWebView() {
80
+ return useSyncExternalStore(subscribeNever, isNativeAppWebView, onServer);
81
+ }
82
+
83
+ //# sourceMappingURL=native-app-web-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/native-app-web-view.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useSyncExternalStore } from 'react'\n\n/**\n * Whether a page is running inside the native apps' web view (AGL-3894).\n *\n * The Aglyn apps (iPhone, iPad, Mac, Android, Windows) open the Besigner in\n * an in-app web view. Inside it the app owns what a browser tab would offer:\n * its own push notifications, its own Done button, its own window title. The\n * page uses this to leave those web-only extras out.\n *\n * Two signals, either one enough:\n *\n * - **The user-agent marker.** Every app's web view appends\n * `AglynApp/<version> (<platform>)` to its user agent (WKWebView's\n * `applicationNameForUserAgent`, Android's `userAgentString`, WebView2's\n * `UserAgent`). It is there from the first request, whichever page the\n * view opens first, so it holds even for a build that predates the entry\n * page below.\n * - **The entry page's session mark.** `/auth/besigner` marks the tab when\n * the app opens the Besigner through it (AGL-3850). Session storage lives\n * exactly as long as the web view and never reaches a browser tab.\n *\n * PRESENTATION ONLY. A user agent is whatever the client says it is, so this\n * decides what the page shows (a prompt, a back arrow, a title) and never\n * what anyone may do: no auth, entitlement or security decision reads it.\n */\n\n/** The product token every app's web view adds to its user agent. */\nexport const NATIVE_APP_USER_AGENT_PRODUCT = 'AglynApp'\n\n/** Set by the Besigner entry page for the life of the web view's tab. */\nconst NATIVE_APP_WEB_VIEW_KEY = 'aglyn:native-app-web-view'\n\n/** `AglynApp/<version>` as its own token: not inside a longer product name. */\nconst USER_AGENT_MARKER = new RegExp(\n `(?:^|[\\\\s(;])${NATIVE_APP_USER_AGENT_PRODUCT}/[^\\\\s/]+`,\n)\n\n/**\n * The marker the apps append, for the native code's specs and for anyone\n * reading this file to know the exact shape: `AglynApp/1.4.0 (ios)`.\n */\nexport function nativeAppUserAgentMarker(\n version: string,\n platform: string,\n): string {\n return `${NATIVE_APP_USER_AGENT_PRODUCT}/${version || '0'} (${platform})`\n}\n\n/** Whether a user-agent string carries the apps' marker. */\nexport function userAgentNamesNativeApp(\n userAgent: string | null | undefined,\n): boolean {\n return typeof userAgent === 'string' && USER_AGENT_MARKER.test(userAgent)\n}\n\n/**\n * Remember, for this tab, that it is the native apps' web view. Called by the\n * Besigner entry page the apps open first.\n */\nexport function markNativeAppWebView(): void {\n try {\n window.sessionStorage.setItem(NATIVE_APP_WEB_VIEW_KEY, '1')\n } catch {\n // Storage refused: the user-agent marker still answers.\n }\n}\n\n/** Whether this page is inside the native apps' web view. */\nexport function isNativeAppWebView(): boolean {\n if (typeof window === 'undefined') return false\n if (userAgentNamesNativeApp(window.navigator?.userAgent)) return true\n try {\n return window.sessionStorage.getItem(NATIVE_APP_WEB_VIEW_KEY) === '1'\n } catch {\n return false\n }\n}\n\nconst subscribeNever = (): (() => void) => () => undefined\nconst onServer = (): boolean => false\n\n/**\n * `isNativeAppWebView()` for a render. The server cannot tell, so it renders\n * the browser's page and hydration agrees with it; the client then renders\n * again with the answer. Neither signal changes while a page is open, so\n * there is nothing to subscribe to.\n */\nexport function useIsNativeAppWebView(): boolean {\n return useSyncExternalStore(subscribeNever, isNativeAppWebView, onServer)\n}\n"],"names":["useSyncExternalStore","NATIVE_APP_USER_AGENT_PRODUCT","NATIVE_APP_WEB_VIEW_KEY","USER_AGENT_MARKER","RegExp","nativeAppUserAgentMarker","version","platform","userAgentNamesNativeApp","userAgent","test","markNativeAppWebView","window","sessionStorage","setItem","isNativeAppWebView","navigator","getItem","subscribeNever","undefined","onServer","useIsNativeAppWebView"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,oBAAoB,QAAQ,QAAO;AAE5C;;;;;;;;;;;;;;;;;;;;;;;CAuBC,GAED,mEAAmE,GACnE,OAAO,MAAMC,gCAAgC,WAAU;AAEvD,uEAAuE,GACvE,MAAMC,0BAA0B;AAEhC,6EAA6E,GAC7E,MAAMC,oBAAoB,IAAIC,OAC5B,CAAC,aAAa,EAAEH,8BAA8B,SAAS,CAAC;AAG1D;;;CAGC,GACD,OAAO,SAASI,yBACdC,OAAe,EACfC,QAAgB;IAEhB,OAAO,GAAGN,8BAA8B,CAAC,EAAEK,WAAW,IAAI,EAAE,EAAEC,SAAS,CAAC,CAAC;AAC3E;AAEA,0DAA0D,GAC1D,OAAO,SAASC,wBACdC,SAAoC;IAEpC,OAAO,OAAOA,cAAc,YAAYN,kBAAkBO,IAAI,CAACD;AACjE;AAEA;;;CAGC,GACD,OAAO,SAASE;IACd,IAAI;QACFC,OAAOC,cAAc,CAACC,OAAO,CAACZ,yBAAyB;IACzD,EAAE,eAAM;IACN,wDAAwD;IAC1D;AACF;AAEA,2DAA2D,GAC3D,OAAO,SAASa;QAEcH;IAD5B,IAAI,OAAOA,WAAW,aAAa,OAAO;IAC1C,IAAIJ,yBAAwBI,oBAAAA,OAAOI,SAAS,qBAAhBJ,kBAAkBH,SAAS,GAAG,OAAO;IACjE,IAAI;QACF,OAAOG,OAAOC,cAAc,CAACI,OAAO,CAACf,6BAA6B;IACpE,EAAE,eAAM;QACN,OAAO;IACT;AACF;AAEA,MAAMgB,iBAAiB,IAAoB,IAAMC;AACjD,MAAMC,WAAW,IAAe;AAEhC;;;;;CAKC,GACD,OAAO,SAASC;IACd,OAAOrB,qBAAqBkB,gBAAgBH,oBAAoBK;AAClE"}