@ti-engine/web-framework 1.33.0 → 1.34.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/CHANGELOG.md CHANGED
@@ -2,6 +2,25 @@
2
2
 
3
3
  This document will contain the list of changes made to the framework. The format is based on the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification.
4
4
 
5
+ ## Version 1.34.0
6
+
7
+ * fix(web-app): give the login error element fallback text, so it can never render as an empty box. The message
8
+ has been unreadable since it was added (CA-95): `x-text-label` resolves
9
+ `interface.default.login.error-sign-in-failed` out of **this package's** `web-server-labels.json`, and a consuming
10
+ application configures exactly one labels path — its own — so the key does not resolve there. The directive then
11
+ falls back to the element's own text content, and the element was empty. The result was a red alert box with
12
+ nothing in it: visibly broken, and saying nothing to the person who had just failed to sign in. An application
13
+ that wants it localized adds the key to its own catalogue, which is the same arrangement the Profile and About
14
+ screens already use.
15
+ * fix(web-app): drop the `error` query parameter from the address bar once the login screen has shown it, via the
16
+ new `tiToolbox.clearUrlParam( name )` (`history.replaceState`, so no history entry the visitor never navigated
17
+ to). It is a one-time message, not state: left in place, a refresh replays a sign-in failure that already
18
+ happened, a bookmark captures it, and the login screen cannot be returned to its blank state without editing the
19
+ URL by hand. The parameter itself stays, because a top-level browser navigation — an OAuth callback, or a
20
+ non-HTMX form post — cannot be answered with a body and still leave the visitor on the login page; a redirect is
21
+ the only way, and a redirect carries no payload. HTMX requests were never affected: they already receive the
22
+ error through the `ti:error` `HX-Trigger` and touch no query string.
23
+
5
24
  ## Version 1.33.0
6
25
 
7
26
  * fix(web-handlers)!: refuse an OpenID Connect callback that cannot be completed through the normal error path
@@ -12,12 +12,17 @@
12
12
  <!-- Login card -->
13
13
  <div class="ti-login-card">
14
14
  <!-- Error message -->
15
+ <!-- The element's own text is the FALLBACK the x-text-label directive falls back to, and it has to be
16
+ here: this key lives in the framework's web-server-labels.json, and a consuming application
17
+ configures exactly one labels path — its own — so the framework's catalogue is not loaded and the
18
+ key does not resolve. An empty element therefore rendered an empty red box: visibly broken, saying
19
+ nothing. An application that wants this localized adds the key to its own catalogue. -->
15
20
  <div id="ti-error"
16
21
  class="ti-login-error"
17
22
  x-data="tiLoginError"
18
23
  x-bind:class="{ visible: hasError }"
19
24
  role="alert"
20
- x-text-label="interface.default.login.error-sign-in-failed"></div>
25
+ x-text-label="interface.default.login.error-sign-in-failed">Sign-in failed. Please try again.</div>
21
26
 
22
27
  <!--ti-auth-method:local-->
23
28
  <!-- Local auth form -->
@@ -204,6 +204,32 @@ const configureToolbox = () => {
204
204
  return new URLSearchParams( window.location.search ).get( name );
205
205
  },
206
206
 
207
+ /**
208
+ * Removes a query parameter from the address bar without reloading or adding a history entry.
209
+ * <br/>
210
+ * For a parameter that carries a one-time message: once it has been read and shown, it has done its job, and
211
+ * leaving it in the URL means a refresh or a bookmark replays a failure that is no longer happening.
212
+ * `replaceState` rather than `pushState`, so the back button is not left stepping through states the visitor
213
+ * never navigated to.
214
+ *
215
+ * @method
216
+ * @param {string} name
217
+ * @public
218
+ */
219
+ clearUrlParam( name ) {
220
+ if ( !window.history || typeof window.history.replaceState !== "function" ) {
221
+ return;
222
+ }
223
+ const url = new URL( window.location.href );
224
+ if ( !url.searchParams.has( name ) ) {
225
+ return;
226
+ }
227
+ url.searchParams.delete( name );
228
+ // Keep a bare "?" off the end when the last parameter goes.
229
+ const search = url.searchParams.toString();
230
+ window.history.replaceState( null, "", url.pathname + ( search ? "?" + search : "" ) + url.hash );
231
+ },
232
+
207
233
  /**
208
234
  * Used to get the visible box of the document.
209
235
  *
@@ -1684,6 +1710,10 @@ const configureLoginError = () => {
1684
1710
  init() {
1685
1711
  const tiToolbox = Alpine.store( "tiToolbox" );
1686
1712
  this.hasError = Boolean( tiToolbox.getUrlParam( "error" ) );
1713
+ // The parameter is a one-time message, not state. Read it, show it, drop it — otherwise a refresh (or a
1714
+ // bookmark, or a shared link) replays a sign-in failure that already happened, and the login screen can
1715
+ // never be returned to its blank state without editing the URL by hand.
1716
+ tiToolbox.clearUrlParam( "error" );
1687
1717
  }
1688
1718
  };
1689
1719
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ti-engine/web-framework",
3
- "version": "1.33.0",
3
+ "version": "1.34.0",
4
4
  "description": "A web-framework based on the ti-engine. It provides a customizable ready-to-use web-server microservice and a set of tools for creating web applications. NOTICE: This is still a work in progress and the full architecture, design, and functionality are not available!",
5
5
  "keywords": [
6
6
  "ti-engine",