@valentinkolb/cloud 0.1.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/package.json +69 -0
- package/public/logo.svg +1 -0
- package/scripts/build.ts +113 -0
- package/scripts/preload.ts +73 -0
- package/src/_internal/define-app.ts +399 -0
- package/src/_internal/heartbeat.ts +33 -0
- package/src/_internal/registry.ts +100 -0
- package/src/_internal/runtime-context.ts +38 -0
- package/src/api/accounts-entities.ts +134 -0
- package/src/api/admin-lifecycle.ts +210 -0
- package/src/api/auth/schemas.ts +28 -0
- package/src/api/auth.ts +230 -0
- package/src/api/index.ts +66 -0
- package/src/api/me.ts +206 -0
- package/src/api/search/schemas.ts +43 -0
- package/src/api/search.ts +130 -0
- package/src/clients/core.ts +19 -0
- package/src/config/env.ts +23 -0
- package/src/config/index.ts +6 -0
- package/src/config/ssr.ts +58 -0
- package/src/contracts/app.ts +140 -0
- package/src/contracts/index.ts +5 -0
- package/src/contracts/profile.ts +67 -0
- package/src/contracts/registry.ts +50 -0
- package/src/contracts/settings-types.ts +84 -0
- package/src/contracts/shared.ts +258 -0
- package/src/contracts/widgets.ts +121 -0
- package/src/index.ts +6 -0
- package/src/server/api/index.ts +1 -0
- package/src/server/api/respond.ts +55 -0
- package/src/server/api-client.ts +54 -0
- package/src/server/app-context.ts +39 -0
- package/src/server/index.ts +62 -0
- package/src/server/middleware/auth.ts +168 -0
- package/src/server/middleware/index.ts +7 -0
- package/src/server/middleware/middleware.ts +47 -0
- package/src/server/middleware/openapi.ts +126 -0
- package/src/server/middleware/rate-limit.ts +126 -0
- package/src/server/middleware/request-logger.ts +41 -0
- package/src/server/middleware/validator.ts +35 -0
- package/src/server/services/access.ts +294 -0
- package/src/server/services/freeipa/client.ts +100 -0
- package/src/server/services/freeipa/index.ts +9 -0
- package/src/server/services/freeipa/session.ts +78 -0
- package/src/server/services/freeipa/tls.ts +48 -0
- package/src/server/services/freeipa/util.ts +60 -0
- package/src/server/services/geo.ts +154 -0
- package/src/server/services/index.ts +28 -0
- package/src/server/services/services.ts +13 -0
- package/src/services/account-lifecycle/audit.ts +41 -0
- package/src/services/account-lifecycle/index.ts +907 -0
- package/src/services/account-lifecycle/scheduler.ts +347 -0
- package/src/services/account-model.ts +21 -0
- package/src/services/accounts/app.ts +966 -0
- package/src/services/accounts/authz.ts +22 -0
- package/src/services/accounts/base-group.ts +11 -0
- package/src/services/accounts/base-user.ts +45 -0
- package/src/services/accounts/entities.ts +529 -0
- package/src/services/accounts/group-sql.ts +106 -0
- package/src/services/accounts/groups.ts +246 -0
- package/src/services/accounts/index.ts +14 -0
- package/src/services/accounts/ipa-data.ts +64 -0
- package/src/services/accounts/lifecycle.ts +2 -0
- package/src/services/accounts/local-groups.ts +491 -0
- package/src/services/accounts/model.ts +135 -0
- package/src/services/accounts/switching.ts +117 -0
- package/src/services/accounts/users.ts +714 -0
- package/src/services/auth-flows/index.ts +6 -0
- package/src/services/auth-flows/ipa.ts +128 -0
- package/src/services/auth-flows/magic-link.ts +119 -0
- package/src/services/freeipa-config.ts +89 -0
- package/src/services/index.ts +46 -0
- package/src/services/ipa/auth.ts +122 -0
- package/src/services/ipa/groups.ts +684 -0
- package/src/services/ipa/guard.ts +17 -0
- package/src/services/ipa/index.ts +17 -0
- package/src/services/ipa/profile.ts +90 -0
- package/src/services/ipa/search.ts +154 -0
- package/src/services/ipa/sync.ts +740 -0
- package/src/services/ipa/users.ts +794 -0
- package/src/services/logging/index.ts +294 -0
- package/src/services/notifications/email.ts +123 -0
- package/src/services/notifications/index.ts +413 -0
- package/src/services/postgres.ts +51 -0
- package/src/services/providers/index.ts +27 -0
- package/src/services/providers/local/auth.ts +13 -0
- package/src/services/providers/local/index.ts +4 -0
- package/src/services/providers/local/users.ts +255 -0
- package/src/services/session/index.ts +137 -0
- package/src/services/settings/api.ts +61 -0
- package/src/services/settings/app.ts +101 -0
- package/src/services/settings/crypto.ts +69 -0
- package/src/services/settings/defaults.ts +824 -0
- package/src/services/settings/index.ts +203 -0
- package/src/services/settings/namespace.ts +9 -0
- package/src/services/settings/snapshot.ts +49 -0
- package/src/services/settings/store.ts +179 -0
- package/src/services/settings/templates.ts +10 -0
- package/src/services/weather/forecast.ts +287 -0
- package/src/services/weather/geo.ts +110 -0
- package/src/services/weather/index.ts +99 -0
- package/src/services/weather/location.ts +24 -0
- package/src/services/weather/locations.ts +125 -0
- package/src/services/weather/migrate.ts +22 -0
- package/src/services/weather/types.ts +61 -0
- package/src/services/weather/ui.ts +50 -0
- package/src/shared/account-display.ts +17 -0
- package/src/shared/account-session.ts +15 -0
- package/src/shared/icons.ts +109 -0
- package/src/shared/index.ts +10 -0
- package/src/shared/markdown/client.ts +130 -0
- package/src/shared/markdown/extensions/code.ts +58 -0
- package/src/shared/markdown/extensions/images.ts +43 -0
- package/src/shared/markdown/extensions/info-blocks.ts +93 -0
- package/src/shared/markdown/extensions/katex.ts +120 -0
- package/src/shared/markdown/extensions/links.ts +34 -0
- package/src/shared/markdown/extensions/tables.ts +88 -0
- package/src/shared/markdown/extensions/task-list.ts +53 -0
- package/src/shared/markdown/index.ts +97 -0
- package/src/shared/markdown/shared.ts +36 -0
- package/src/ssr/AdminLayout.tsx +42 -0
- package/src/ssr/AdminSidebar.tsx +95 -0
- package/src/ssr/Footer.island.tsx +62 -0
- package/src/ssr/GlobalSearchDialog.tsx +389 -0
- package/src/ssr/GlobalSearchHelpDialog.tsx +106 -0
- package/src/ssr/GlobalSearchTrigger.island.tsx +42 -0
- package/src/ssr/HotkeysHelpRail.island.tsx +99 -0
- package/src/ssr/Layout.tsx +326 -0
- package/src/ssr/MoreAppsDropdown.island.tsx +61 -0
- package/src/ssr/NavMenu.island.tsx +108 -0
- package/src/ssr/ThemeToggleRail.island.tsx +27 -0
- package/src/ssr/index.ts +5 -0
- package/src/ssr/islands/SearchBar.island.tsx +77 -0
- package/src/ssr/islands/index.ts +1 -0
- package/src/ssr/runtime.ts +22 -0
- package/src/styles/base-popover.css +28 -0
- package/src/styles/effects.css +65 -0
- package/src/styles/global.css +133 -0
- package/src/styles/input.css +54 -0
- package/src/styles/tokens.css +35 -0
- package/src/styles/utilities-buttons.css +125 -0
- package/src/styles/utilities-feedback.css +65 -0
- package/src/styles/utilities-layout.css +122 -0
- package/src/styles/utilities-navigation.css +196 -0
- package/src/types/ambient.d.ts +8 -0
- package/src/ui/admin-settings.tsx +148 -0
- package/src/ui/dialog-core.ts +146 -0
- package/src/ui/filter/FilterChip.tsx +196 -0
- package/src/ui/filter/index.ts +2 -0
- package/src/ui/index.ts +19 -0
- package/src/ui/input/Checkbox.tsx +55 -0
- package/src/ui/input/ColorInput.tsx +122 -0
- package/src/ui/input/DateTimeInput.tsx +86 -0
- package/src/ui/input/ImageInput.tsx +170 -0
- package/src/ui/input/NumberInput.tsx +113 -0
- package/src/ui/input/PinInput.tsx +169 -0
- package/src/ui/input/SegmentedControl.tsx +99 -0
- package/src/ui/input/Select.tsx +288 -0
- package/src/ui/input/SelectChip.tsx +61 -0
- package/src/ui/input/Slider.tsx +118 -0
- package/src/ui/input/Switch.tsx +62 -0
- package/src/ui/input/TagsInput.tsx +115 -0
- package/src/ui/input/TextInput.tsx +160 -0
- package/src/ui/input/index.ts +13 -0
- package/src/ui/input/types.ts +42 -0
- package/src/ui/input/util.tsx +105 -0
- package/src/ui/ipa/Avatar.tsx +28 -0
- package/src/ui/ipa/GroupView.tsx +36 -0
- package/src/ui/ipa/LoginBtn.tsx +16 -0
- package/src/ui/ipa/UserView.tsx +58 -0
- package/src/ui/ipa/index.ts +4 -0
- package/src/ui/misc/ContextMenu.tsx +211 -0
- package/src/ui/misc/CopyButton.tsx +28 -0
- package/src/ui/misc/Dropdown.tsx +194 -0
- package/src/ui/misc/EntitySearch.tsx +213 -0
- package/src/ui/misc/Lightbox.tsx +194 -0
- package/src/ui/misc/LinkCard.tsx +34 -0
- package/src/ui/misc/LogEntriesTable.tsx +61 -0
- package/src/ui/misc/MarkdownView.tsx +65 -0
- package/src/ui/misc/Pagination.tsx +51 -0
- package/src/ui/misc/PermissionEditor.tsx +379 -0
- package/src/ui/misc/ProgressBar.tsx +47 -0
- package/src/ui/misc/RemoveBtn.tsx +27 -0
- package/src/ui/misc/StatCell.tsx +90 -0
- package/src/ui/misc/index.ts +18 -0
- package/src/ui/navigation.ts +32 -0
- package/src/ui/prompts.tsx +854 -0
- package/src/ui/sidebar.tsx +468 -0
- package/src/ui/widgets/Widget.tsx +62 -0
- package/src/ui/widgets/WidgetCard.tsx +19 -0
- package/src/ui/widgets/WidgetHero.tsx +39 -0
- package/src/ui/widgets/WidgetList.tsx +84 -0
- package/src/ui/widgets/WidgetPills.tsx +68 -0
- package/src/ui/widgets/WidgetStat.tsx +67 -0
- package/src/ui/widgets/WidgetStatus.tsx +62 -0
- package/src/ui/widgets/index.ts +9 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { sql } from "bun";
|
|
2
|
+
import type { UserProfile, UserProvider } from "../../contracts/shared";
|
|
3
|
+
import * as settings from "../settings";
|
|
4
|
+
import type { IpaAccountTransitionPolicy } from "./model";
|
|
5
|
+
|
|
6
|
+
type SqlExecutor = typeof sql;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Remove provider-scoped group and manager relations for a user.
|
|
10
|
+
* Local group memberships are intentionally preserved when switching providers.
|
|
11
|
+
*/
|
|
12
|
+
export const clearUserRelationsForProvider = async (params: {
|
|
13
|
+
userId: string;
|
|
14
|
+
provider: UserProvider;
|
|
15
|
+
db?: SqlExecutor;
|
|
16
|
+
}): Promise<void> => {
|
|
17
|
+
const db = params.db ?? sql;
|
|
18
|
+
|
|
19
|
+
await db`
|
|
20
|
+
DELETE FROM auth.user_groups_v2 ug
|
|
21
|
+
USING auth.groups g
|
|
22
|
+
WHERE ug.group_id = g.id
|
|
23
|
+
AND ug.user_id = ${params.userId}
|
|
24
|
+
AND g.provider = ${params.provider}
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
await db`
|
|
28
|
+
DELETE FROM auth.group_manager_users_v2 gmu
|
|
29
|
+
USING auth.groups g
|
|
30
|
+
WHERE gmu.group_id = g.id
|
|
31
|
+
AND gmu.user_id = ${params.userId}
|
|
32
|
+
AND g.provider = ${params.provider}
|
|
33
|
+
`;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const getLocalExpiryDays = async (profile: UserProfile): Promise<number> => {
|
|
37
|
+
if (profile === "guest") {
|
|
38
|
+
const configured = await settings.get<number | null>("user.account.local_guest_expires_days");
|
|
39
|
+
return typeof configured === "number" ? configured : 365;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const configured = await settings.get<number | null>("user.account.local_user_expires_days");
|
|
43
|
+
return typeof configured === "number" ? configured : 0;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const resolveDefaultLocalAccountExpiry = async (profile: UserProfile): Promise<Date | null> => {
|
|
47
|
+
const days = await getLocalExpiryDays(profile);
|
|
48
|
+
if (days <= 0) return null;
|
|
49
|
+
return new Date(Date.now() + days * 24 * 60 * 60 * 1000);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const resolveIpaTransitionTarget = async (params: {
|
|
53
|
+
currentProfile: UserProfile;
|
|
54
|
+
policy: Exclude<IpaAccountTransitionPolicy, "delete">;
|
|
55
|
+
}): Promise<{ targetProfile: UserProfile; accountExpires: Date | null }> => {
|
|
56
|
+
const targetProfile =
|
|
57
|
+
params.policy === "demote_to_local"
|
|
58
|
+
? params.currentProfile
|
|
59
|
+
: params.policy === "demote_to_local_user"
|
|
60
|
+
? "user"
|
|
61
|
+
: "guest";
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
targetProfile,
|
|
65
|
+
accountExpires: await resolveDefaultLocalAccountExpiry(targetProfile),
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const transitionIpaUserToLocal = async (params: {
|
|
70
|
+
userId: string;
|
|
71
|
+
targetProfile: UserProfile;
|
|
72
|
+
accountExpires: Date | null;
|
|
73
|
+
db?: SqlExecutor;
|
|
74
|
+
}): Promise<void> => {
|
|
75
|
+
const db = params.db ?? sql;
|
|
76
|
+
|
|
77
|
+
await db`
|
|
78
|
+
UPDATE auth.users
|
|
79
|
+
SET provider = 'local',
|
|
80
|
+
profile = ${params.targetProfile},
|
|
81
|
+
admin = false,
|
|
82
|
+
account_expires = ${params.accountExpires}
|
|
83
|
+
WHERE id = ${params.userId}::uuid
|
|
84
|
+
`;
|
|
85
|
+
|
|
86
|
+
await db`
|
|
87
|
+
DELETE FROM auth.user_ipa_data
|
|
88
|
+
WHERE user_id = ${params.userId}::uuid
|
|
89
|
+
`;
|
|
90
|
+
|
|
91
|
+
await clearUserRelationsForProvider({
|
|
92
|
+
userId: params.userId,
|
|
93
|
+
provider: "ipa",
|
|
94
|
+
db,
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export const applyIpaAccountTransitionPolicy = async (params: {
|
|
99
|
+
userId: string;
|
|
100
|
+
currentProfile: UserProfile;
|
|
101
|
+
policy: Exclude<IpaAccountTransitionPolicy, "delete">;
|
|
102
|
+
db?: SqlExecutor;
|
|
103
|
+
}): Promise<{ targetProfile: UserProfile; accountExpires: Date | null }> => {
|
|
104
|
+
const target = await resolveIpaTransitionTarget({
|
|
105
|
+
currentProfile: params.currentProfile,
|
|
106
|
+
policy: params.policy,
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
await transitionIpaUserToLocal({
|
|
110
|
+
userId: params.userId,
|
|
111
|
+
targetProfile: target.targetProfile,
|
|
112
|
+
accountExpires: target.accountExpires,
|
|
113
|
+
db: params.db,
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
return target;
|
|
117
|
+
};
|