@ossy/platform 3.0.5 → 3.0.7
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 +13 -13
- package/src/runtime.js +2 -1
- package/src/server.js +19 -2
- package/src/user-app-settings.js +14 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ossy/platform",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.7",
|
|
4
4
|
"description": "Ossy application server runtime",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -44,17 +44,17 @@
|
|
|
44
44
|
"@aws-sdk/util-create-request": "^3.972.26",
|
|
45
45
|
"@aws-sdk/util-format-url": "^3.972.17",
|
|
46
46
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
47
|
-
"@ossy/config": "^3.0.
|
|
48
|
-
"@ossy/event-store": "^3.0.
|
|
49
|
-
"@ossy/locale": "^3.0.
|
|
50
|
-
"@ossy/manifest": "^3.0.
|
|
51
|
-
"@ossy/observability": "^3.0.
|
|
52
|
-
"@ossy/policies": "^3.0.
|
|
53
|
-
"@ossy/schema": "^3.0.
|
|
54
|
-
"@ossy/sdk": "^3.0.
|
|
55
|
-
"@ossy/tokens": "^3.0.
|
|
56
|
-
"@ossy/users": "^3.0.
|
|
57
|
-
"@ossy/workspaces": "^3.0.
|
|
47
|
+
"@ossy/config": "^3.0.7",
|
|
48
|
+
"@ossy/event-store": "^3.0.7",
|
|
49
|
+
"@ossy/locale": "^3.0.7",
|
|
50
|
+
"@ossy/manifest": "^3.0.7",
|
|
51
|
+
"@ossy/observability": "^3.0.7",
|
|
52
|
+
"@ossy/policies": "^3.0.7",
|
|
53
|
+
"@ossy/schema": "^3.0.7",
|
|
54
|
+
"@ossy/sdk": "^3.0.7",
|
|
55
|
+
"@ossy/tokens": "^3.0.7",
|
|
56
|
+
"@ossy/users": "^3.0.7",
|
|
57
|
+
"@ossy/workspaces": "^3.0.7",
|
|
58
58
|
"cookie-parser": "^1.4.7",
|
|
59
59
|
"dotenv": ">=16.0.0 <18.0.0",
|
|
60
60
|
"express": ">=5.0.0 <6.0.0",
|
|
@@ -74,5 +74,5 @@
|
|
|
74
74
|
"src",
|
|
75
75
|
"Dockerfile"
|
|
76
76
|
],
|
|
77
|
-
"gitHead": "
|
|
77
|
+
"gitHead": "5010f51795d5b8f4c63ef52495f4b2935b801b3f"
|
|
78
78
|
}
|
package/src/runtime.js
CHANGED
|
@@ -86,7 +86,8 @@ export async function startRuntime ({ port } = {}) {
|
|
|
86
86
|
if (userSettings.workspaceId && !req.get('workspaceId')) {
|
|
87
87
|
req.headers.workspaceid = userSettings.workspaceId
|
|
88
88
|
}
|
|
89
|
-
|
|
89
|
+
// Prefer a verified signed auth cookie; fall back to presence only when unsigned.
|
|
90
|
+
req.isAuthenticated = !!(req.signedCookies?.auth)
|
|
90
91
|
next()
|
|
91
92
|
})
|
|
92
93
|
|
package/src/server.js
CHANGED
|
@@ -39,6 +39,10 @@ import {
|
|
|
39
39
|
buildEnableablePackageSet,
|
|
40
40
|
setEnableablePackages,
|
|
41
41
|
} from '@ossy/workspaces/entitlements'
|
|
42
|
+
import {
|
|
43
|
+
clearAuthCookie,
|
|
44
|
+
clearWorkspaceFromUserAppSettings,
|
|
45
|
+
} from './user-app-settings.js'
|
|
42
46
|
const log = createLogger('@ossy/platform')
|
|
43
47
|
const MONGO_TIMEOUT_MS = resolveTimeoutMs('OSSY_MONGO_TIMEOUT_MS', 10_000)
|
|
44
48
|
const SSR_RENDER_TIMEOUT_MS = resolveTimeoutMs('OSSY_SSR_RENDER_TIMEOUT_MS', 30_000)
|
|
@@ -325,11 +329,15 @@ export async function startServer (options = {}) {
|
|
|
325
329
|
if (userSettings.workspaceId && !req.get('workspaceId')) {
|
|
326
330
|
req.headers.workspaceid = userSettings.workspaceId
|
|
327
331
|
}
|
|
328
|
-
const cookieHeader = req.headers.cookie
|
|
329
|
-
req.isAuthenticated = cookieHeader ? cookieHeader.includes('auth=') : false
|
|
330
332
|
next()
|
|
331
333
|
})
|
|
332
334
|
app.use(UsersMiddleware.AuthenticateUser)
|
|
335
|
+
app.use((req, _res, next) => {
|
|
336
|
+
// After auth resolution — not raw Cookie header (stale/invalid `auth=` looked "logged in").
|
|
337
|
+
const anon = ConfigService.AnonymousUserId
|
|
338
|
+
req.isAuthenticated = !!(req.userId && req.userId !== anon && req.userId !== 'anonymous')
|
|
339
|
+
next()
|
|
340
|
+
})
|
|
333
341
|
app.use(WorkspacesMiddleware.ExtractWorkspaceId())
|
|
334
342
|
app.use(createSlowRequestLogger(log))
|
|
335
343
|
if (fs.existsSync(publicDir)) app.use(express.static(publicDir))
|
|
@@ -404,8 +412,17 @@ export async function startServer (options = {}) {
|
|
|
404
412
|
{ abortController: actionAbort },
|
|
405
413
|
)
|
|
406
414
|
actionTimer.finish({ statusCode: 200 })
|
|
415
|
+
if (actionId === '@ossy/authentication/actions/sign-out') {
|
|
416
|
+
clearAuthCookie(res)
|
|
417
|
+
clearWorkspaceFromUserAppSettings(req, res)
|
|
418
|
+
}
|
|
407
419
|
res.json(result ?? { ok: true })
|
|
408
420
|
} catch (err) {
|
|
421
|
+
// Still clear auth on sign-out failures so a broken session can recover.
|
|
422
|
+
if (actionId === '@ossy/authentication/actions/sign-out') {
|
|
423
|
+
clearAuthCookie(res)
|
|
424
|
+
clearWorkspaceFromUserAppSettings(req, res)
|
|
425
|
+
}
|
|
409
426
|
actionTimer.finish({
|
|
410
427
|
statusCode: err instanceof OperationTimeoutError ? 504 : (err?.status ?? 500),
|
|
411
428
|
timedOut: err instanceof OperationTimeoutError,
|
package/src/user-app-settings.js
CHANGED
|
@@ -13,6 +13,7 @@ export function mergeUserAppSettingsCookie (req, res, partial) {
|
|
|
13
13
|
res.cookie(USER_SETTINGS_COOKIE, JSON.stringify(updated), {
|
|
14
14
|
httpOnly: true,
|
|
15
15
|
signed: true,
|
|
16
|
+
path: '/',
|
|
16
17
|
expires: new Date(Date.now() + USER_SETTINGS_MAX_AGE_MS),
|
|
17
18
|
})
|
|
18
19
|
}
|
|
@@ -21,12 +22,13 @@ export function clearWorkspaceFromUserAppSettings (req, res) {
|
|
|
21
22
|
const settings = readUserAppSettings(req)
|
|
22
23
|
delete settings.workspaceId
|
|
23
24
|
if (Object.keys(settings).length === 0) {
|
|
24
|
-
res.clearCookie(USER_SETTINGS_COOKIE)
|
|
25
|
+
res.clearCookie(USER_SETTINGS_COOKIE, { httpOnly: true, signed: true, path: '/' })
|
|
25
26
|
return
|
|
26
27
|
}
|
|
27
28
|
res.cookie(USER_SETTINGS_COOKIE, JSON.stringify(settings), {
|
|
28
29
|
httpOnly: true,
|
|
29
30
|
signed: true,
|
|
31
|
+
path: '/',
|
|
30
32
|
expires: new Date(Date.now() + USER_SETTINGS_MAX_AGE_MS),
|
|
31
33
|
})
|
|
32
34
|
}
|
|
@@ -35,10 +37,20 @@ export function setAuthCookie (res, token) {
|
|
|
35
37
|
res.cookie(AUTH_COOKIE, token, {
|
|
36
38
|
httpOnly: true,
|
|
37
39
|
signed: true,
|
|
40
|
+
path: '/',
|
|
38
41
|
expires: new Date(Date.now() + AUTH_MAX_AGE_MS),
|
|
39
42
|
})
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
export function clearAuthCookie (res) {
|
|
43
|
-
|
|
46
|
+
// Options must match setAuthCookie or browsers keep the cookie.
|
|
47
|
+
const clearOpts = { httpOnly: true, path: '/' }
|
|
48
|
+
res.clearCookie(AUTH_COOKIE, clearOpts)
|
|
49
|
+
res.clearCookie(AUTH_COOKIE, { ...clearOpts, signed: true })
|
|
50
|
+
// Force-overwrite in case clearCookie options don't match an older cookie.
|
|
51
|
+
res.cookie(AUTH_COOKIE, '', {
|
|
52
|
+
...clearOpts,
|
|
53
|
+
signed: true,
|
|
54
|
+
expires: new Date(0),
|
|
55
|
+
})
|
|
44
56
|
}
|