ugly-app 0.1.734 → 0.1.735
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/cli/version.d.ts +1 -1
- package/dist/cli/version.js +1 -1
- package/dist/client/auth/startLogin.d.ts +11 -0
- package/dist/client/auth/startLogin.d.ts.map +1 -1
- package/dist/client/auth/startLogin.js +26 -0
- package/dist/client/auth/startLogin.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/version.ts +1 -1
- package/src/client/auth/startLogin.test.ts +56 -0
- package/src/client/auth/startLogin.ts +28 -0
package/dist/cli/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const CLI_VERSION = "0.1.
|
|
1
|
+
export declare const CLI_VERSION = "0.1.735";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/cli/version.js
CHANGED
|
@@ -26,6 +26,17 @@ export declare function startUglyBotAuthorize(opts?: {
|
|
|
26
26
|
scopes?: string[];
|
|
27
27
|
aiCapCents?: number;
|
|
28
28
|
}): void;
|
|
29
|
+
/**
|
|
30
|
+
* A dev/preview origin that ugly.bot's `/oauth/silent` redirect mode will reject
|
|
31
|
+
* with 400 "Invalid origin": plain-http (localhost dev servers) or a
|
|
32
|
+
* `*.trycloudflare.com` quick-tunnel (Ugly Studio's Preview panel publishes the
|
|
33
|
+
* dev server there so mobile can reach it). The apex silent-SSO top-level
|
|
34
|
+
* redirect must be skipped for these, or the app strands on ugly.bot's blank 400.
|
|
35
|
+
*/
|
|
36
|
+
export declare function isDevPreviewOrigin(loc: {
|
|
37
|
+
protocol: string;
|
|
38
|
+
hostname: string;
|
|
39
|
+
}): boolean;
|
|
29
40
|
/**
|
|
30
41
|
* Silent SSO for apex-domain apps (ugly.chat, ugly.press, …) that don't share
|
|
31
42
|
* ugly.bot's `auth_token` cookie. Adopts an existing ugly.bot session with NO
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startLogin.d.ts","sourceRoot":"","sources":["../../../src/client/auth/startLogin.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,iBAAiB;IAChC,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,iBAAsB,GAAG,IAAI,CAmCpE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GACpD,IAAI,CAUN;AAID;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,
|
|
1
|
+
{"version":3,"file":"startLogin.d.ts","sourceRoot":"","sources":["../../../src/client/auth/startLogin.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,iBAAiB;IAChC,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,iBAAsB,GAAG,IAAI,CAmCpE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GACpD,IAAI,CAUN;AAID;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAUvF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAuB1C;AAED,kFAAkF;AAClF,wBAAgB,kBAAkB,IAAI,IAAI,CAMzC;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAM1C;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAO1C"}
|
|
@@ -78,6 +78,22 @@ export function startUglyBotAuthorize(opts = {}) {
|
|
|
78
78
|
window.location.assign(`${UGLY_BOT_URL}/oauth?${params.toString()}`);
|
|
79
79
|
}
|
|
80
80
|
const SILENT_SSO_TRIED_KEY = 'uglySilentSsoTried';
|
|
81
|
+
/**
|
|
82
|
+
* A dev/preview origin that ugly.bot's `/oauth/silent` redirect mode will reject
|
|
83
|
+
* with 400 "Invalid origin": plain-http (localhost dev servers) or a
|
|
84
|
+
* `*.trycloudflare.com` quick-tunnel (Ugly Studio's Preview panel publishes the
|
|
85
|
+
* dev server there so mobile can reach it). The apex silent-SSO top-level
|
|
86
|
+
* redirect must be skipped for these, or the app strands on ugly.bot's blank 400.
|
|
87
|
+
*/
|
|
88
|
+
export function isDevPreviewOrigin(loc) {
|
|
89
|
+
const host = loc.hostname;
|
|
90
|
+
return (loc.protocol !== 'https:' ||
|
|
91
|
+
host === 'localhost' ||
|
|
92
|
+
host === '127.0.0.1' ||
|
|
93
|
+
host === '[::1]' ||
|
|
94
|
+
host === '::1' ||
|
|
95
|
+
host.endsWith('.trycloudflare.com'));
|
|
96
|
+
}
|
|
81
97
|
/**
|
|
82
98
|
* Silent SSO for apex-domain apps (ugly.chat, ugly.press, …) that don't share
|
|
83
99
|
* ugly.bot's `auth_token` cookie. Adopts an existing ugly.bot session with NO
|
|
@@ -98,6 +114,16 @@ const SILENT_SSO_TRIED_KEY = 'uglySilentSsoTried';
|
|
|
98
114
|
export function attemptSilentSso() {
|
|
99
115
|
if (typeof window === 'undefined')
|
|
100
116
|
return false;
|
|
117
|
+
// Dev/preview origins — plain-http localhost or a *.trycloudflare.com preview
|
|
118
|
+
// tunnel (Ugly Studio's Preview panel exposes the dev server there for mobile)
|
|
119
|
+
// — are never allow-listed by ugly.bot's `/oauth/silent` redirect mode. It
|
|
120
|
+
// returns 400 "Invalid origin" (an open-redirect guard), and since this is a
|
|
121
|
+
// top-level `location.replace`, the app is STRANDED on that blank error page —
|
|
122
|
+
// "nothing shows up in the preview". Skip the redirect for those origins and
|
|
123
|
+
// render normally (logged-out); the hidden-iframe `silentAuthSync` still adopts
|
|
124
|
+
// a session without navigating away.
|
|
125
|
+
if (isDevPreviewOrigin(window.location))
|
|
126
|
+
return false;
|
|
101
127
|
try {
|
|
102
128
|
if (sessionStorage.getItem(SILENT_SSO_TRIED_KEY))
|
|
103
129
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startLogin.js","sourceRoot":"","sources":["../../../src/client/auth/startLogin.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"startLogin.js","sourceRoot":"","sources":["../../../src/client/auth/startLogin.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ugly-app",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.735",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"comment:files": "Allowlist what ships to npm. dist = runtime; src = sourcemap targets (dist/*.js.map reference ../../src/); templates = CLI scaffold. Everything else at repo root (.pgdata local Postgres, coverage, assets/icons sources, test/, test-results/) is excluded by omission. The !negations strip the scaffold's installed deps + cruft (templates/node_modules is 200MB+ and must never ship). package.json/README/LICENSE ship automatically.",
|
|
6
6
|
"files": [
|
package/src/cli/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Auto-generated by prebuild — do not edit manually
|
|
2
|
-
export const CLI_VERSION = "0.1.
|
|
2
|
+
export const CLI_VERSION = "0.1.735";
|
|
@@ -30,3 +30,59 @@ describe('startUglyBotAuthorize', () => {
|
|
|
30
30
|
expect(url).not.toContain('ai_cap=');
|
|
31
31
|
});
|
|
32
32
|
});
|
|
33
|
+
|
|
34
|
+
describe('isDevPreviewOrigin', () => {
|
|
35
|
+
it('flags plain-http, localhost, loopback, and trycloudflare preview origins', async () => {
|
|
36
|
+
const { isDevPreviewOrigin } = await import('./startLogin');
|
|
37
|
+
expect(isDevPreviewOrigin({ protocol: 'http:', hostname: 'localhost' })).toBe(true);
|
|
38
|
+
expect(isDevPreviewOrigin({ protocol: 'http:', hostname: '127.0.0.1' })).toBe(true);
|
|
39
|
+
expect(isDevPreviewOrigin({ protocol: 'https:', hostname: '127.0.0.1' })).toBe(true);
|
|
40
|
+
expect(isDevPreviewOrigin({ protocol: 'https:', hostname: 'abc-def-ghi.trycloudflare.com' })).toBe(true);
|
|
41
|
+
expect(isDevPreviewOrigin({ protocol: 'http:', hostname: 'ugly.press' })).toBe(true); // plain http
|
|
42
|
+
});
|
|
43
|
+
it('does NOT flag real https apex/subdomain production origins', async () => {
|
|
44
|
+
const { isDevPreviewOrigin } = await import('./startLogin');
|
|
45
|
+
expect(isDevPreviewOrigin({ protocol: 'https:', hostname: 'ugly.press' })).toBe(false);
|
|
46
|
+
expect(isDevPreviewOrigin({ protocol: 'https:', hostname: 'ugly.chat' })).toBe(false);
|
|
47
|
+
expect(isDevPreviewOrigin({ protocol: 'https:', hostname: 'code.ugly.bot' })).toBe(false);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('attemptSilentSso — dev/preview guard', () => {
|
|
52
|
+
function stubLoc(protocol: string, hostname: string): ReturnType<typeof vi.fn> {
|
|
53
|
+
const replace = vi.fn();
|
|
54
|
+
vi.stubGlobal('window', {
|
|
55
|
+
location: { protocol, hostname, origin: `${protocol}//${hostname}`, pathname: '/', search: '', hash: '', replace },
|
|
56
|
+
__UGLY_BOT_URL__: 'https://ugly.bot',
|
|
57
|
+
} as unknown as Window & typeof globalThis);
|
|
58
|
+
vi.stubGlobal('sessionStorage', {
|
|
59
|
+
_m: new Map<string, string>(),
|
|
60
|
+
getItem(k: string) { return this._m.get(k) ?? null; },
|
|
61
|
+
setItem(k: string, v: string) { this._m.set(k, v); },
|
|
62
|
+
removeItem(k: string) { this._m.delete(k); },
|
|
63
|
+
} as unknown as Storage);
|
|
64
|
+
return replace;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
it('does NOT redirect (renders normally) on a localhost preview origin', async () => {
|
|
68
|
+
const replace = stubLoc('http:', 'localhost');
|
|
69
|
+
const { attemptSilentSso } = await import('./startLogin');
|
|
70
|
+
expect(attemptSilentSso()).toBe(false);
|
|
71
|
+
expect(replace).not.toHaveBeenCalled();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('does NOT redirect on a trycloudflare preview tunnel origin', async () => {
|
|
75
|
+
const replace = stubLoc('https:', 'gamma-delta-epsilon.trycloudflare.com');
|
|
76
|
+
const { attemptSilentSso } = await import('./startLogin');
|
|
77
|
+
expect(attemptSilentSso()).toBe(false);
|
|
78
|
+
expect(replace).not.toHaveBeenCalled();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('DOES redirect to /oauth/silent on a real https apex production origin', async () => {
|
|
82
|
+
const replace = stubLoc('https:', 'ugly.press');
|
|
83
|
+
const { attemptSilentSso } = await import('./startLogin');
|
|
84
|
+
expect(attemptSilentSso()).toBe(true);
|
|
85
|
+
const url = replace.mock.calls[0]?.[0] as string;
|
|
86
|
+
expect(url).toContain('https://ugly.bot/oauth/silent?origin=https%3A%2F%2Fugly.press');
|
|
87
|
+
});
|
|
88
|
+
});
|
|
@@ -90,6 +90,25 @@ export function startUglyBotAuthorize(
|
|
|
90
90
|
|
|
91
91
|
const SILENT_SSO_TRIED_KEY = 'uglySilentSsoTried';
|
|
92
92
|
|
|
93
|
+
/**
|
|
94
|
+
* A dev/preview origin that ugly.bot's `/oauth/silent` redirect mode will reject
|
|
95
|
+
* with 400 "Invalid origin": plain-http (localhost dev servers) or a
|
|
96
|
+
* `*.trycloudflare.com` quick-tunnel (Ugly Studio's Preview panel publishes the
|
|
97
|
+
* dev server there so mobile can reach it). The apex silent-SSO top-level
|
|
98
|
+
* redirect must be skipped for these, or the app strands on ugly.bot's blank 400.
|
|
99
|
+
*/
|
|
100
|
+
export function isDevPreviewOrigin(loc: { protocol: string; hostname: string }): boolean {
|
|
101
|
+
const host = loc.hostname;
|
|
102
|
+
return (
|
|
103
|
+
loc.protocol !== 'https:' ||
|
|
104
|
+
host === 'localhost' ||
|
|
105
|
+
host === '127.0.0.1' ||
|
|
106
|
+
host === '[::1]' ||
|
|
107
|
+
host === '::1' ||
|
|
108
|
+
host.endsWith('.trycloudflare.com')
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
93
112
|
/**
|
|
94
113
|
* Silent SSO for apex-domain apps (ugly.chat, ugly.press, …) that don't share
|
|
95
114
|
* ugly.bot's `auth_token` cookie. Adopts an existing ugly.bot session with NO
|
|
@@ -109,6 +128,15 @@ const SILENT_SSO_TRIED_KEY = 'uglySilentSsoTried';
|
|
|
109
128
|
*/
|
|
110
129
|
export function attemptSilentSso(): boolean {
|
|
111
130
|
if (typeof window === 'undefined') return false;
|
|
131
|
+
// Dev/preview origins — plain-http localhost or a *.trycloudflare.com preview
|
|
132
|
+
// tunnel (Ugly Studio's Preview panel exposes the dev server there for mobile)
|
|
133
|
+
// — are never allow-listed by ugly.bot's `/oauth/silent` redirect mode. It
|
|
134
|
+
// returns 400 "Invalid origin" (an open-redirect guard), and since this is a
|
|
135
|
+
// top-level `location.replace`, the app is STRANDED on that blank error page —
|
|
136
|
+
// "nothing shows up in the preview". Skip the redirect for those origins and
|
|
137
|
+
// render normally (logged-out); the hidden-iframe `silentAuthSync` still adopts
|
|
138
|
+
// a session without navigating away.
|
|
139
|
+
if (isDevPreviewOrigin(window.location)) return false;
|
|
112
140
|
try {
|
|
113
141
|
if (sessionStorage.getItem(SILENT_SSO_TRIED_KEY)) return false;
|
|
114
142
|
sessionStorage.setItem(SILENT_SSO_TRIED_KEY, '1');
|