@flowselections/google-maps-api-installatie-techniek 1.0.2

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.
Files changed (66) hide show
  1. package/dist-lib/_core-safelist.d.ts +2 -0
  2. package/dist-lib/_core-safelist.d.ts.map +1 -0
  3. package/dist-lib/_core-safelist.js +15 -0
  4. package/dist-lib/components/MapsBeheerPage.d.ts +2 -0
  5. package/dist-lib/components/MapsBeheerPage.d.ts.map +1 -0
  6. package/dist-lib/components/MapsBeheerPage.js +68 -0
  7. package/dist-lib/components/MapsInstallatieLogo.d.ts +6 -0
  8. package/dist-lib/components/MapsInstallatieLogo.d.ts.map +1 -0
  9. package/dist-lib/components/MapsInstallatieLogo.js +4 -0
  10. package/dist-lib/components/maps/MapsDiagnosticsPanel.d.ts +2 -0
  11. package/dist-lib/components/maps/MapsDiagnosticsPanel.d.ts.map +1 -0
  12. package/dist-lib/components/maps/MapsDiagnosticsPanel.js +81 -0
  13. package/dist-lib/components/maps/MapsStatusPanel.d.ts +5 -0
  14. package/dist-lib/components/maps/MapsStatusPanel.d.ts.map +1 -0
  15. package/dist-lib/components/maps/MapsStatusPanel.js +74 -0
  16. package/dist-lib/components/settings/MapsSettingsCard.d.ts +2 -0
  17. package/dist-lib/components/settings/MapsSettingsCard.d.ts.map +1 -0
  18. package/dist-lib/components/settings/MapsSettingsCard.js +15 -0
  19. package/dist-lib/index.d.ts +7 -0
  20. package/dist-lib/index.d.ts.map +1 -0
  21. package/dist-lib/index.js +20 -0
  22. package/dist-lib/integrations/supabase/auth-attacher.d.ts +2 -0
  23. package/dist-lib/integrations/supabase/auth-attacher.d.ts.map +1 -0
  24. package/dist-lib/integrations/supabase/auth-attacher.js +12 -0
  25. package/dist-lib/integrations/supabase/auth-middleware.d.ts +23365 -0
  26. package/dist-lib/integrations/supabase/auth-middleware.d.ts.map +1 -0
  27. package/dist-lib/integrations/supabase/auth-middleware.js +52 -0
  28. package/dist-lib/integrations/supabase/client.d.ts +23361 -0
  29. package/dist-lib/integrations/supabase/client.d.ts.map +1 -0
  30. package/dist-lib/integrations/supabase/client.js +29 -0
  31. package/dist-lib/integrations/supabase/client.server.d.ts +23361 -0
  32. package/dist-lib/integrations/supabase/client.server.d.ts.map +1 -0
  33. package/dist-lib/integrations/supabase/client.server.js +30 -0
  34. package/dist-lib/integrations/supabase/previewAuthStorage.d.ts +6 -0
  35. package/dist-lib/integrations/supabase/previewAuthStorage.d.ts.map +1 -0
  36. package/dist-lib/integrations/supabase/previewAuthStorage.js +92 -0
  37. package/dist-lib/integrations/supabase/types.d.ts +23990 -0
  38. package/dist-lib/integrations/supabase/types.d.ts.map +1 -0
  39. package/dist-lib/integrations/supabase/types.js +92 -0
  40. package/dist-lib/lib/central-auth.server.d.ts +60 -0
  41. package/dist-lib/lib/central-auth.server.d.ts.map +1 -0
  42. package/dist-lib/lib/central-auth.server.js +439 -0
  43. package/dist-lib/lib/google-maps.server.d.ts +22 -0
  44. package/dist-lib/lib/google-maps.server.d.ts.map +1 -0
  45. package/dist-lib/lib/google-maps.server.js +65 -0
  46. package/dist-lib/lib/maps-admin.server.d.ts +17 -0
  47. package/dist-lib/lib/maps-admin.server.d.ts.map +1 -0
  48. package/dist-lib/lib/maps-admin.server.js +121 -0
  49. package/dist-lib/lib/maps-diagnostics.server.d.ts +4 -0
  50. package/dist-lib/lib/maps-diagnostics.server.d.ts.map +1 -0
  51. package/dist-lib/lib/maps-diagnostics.server.js +137 -0
  52. package/dist-lib/lib/maps-processor.server.d.ts +16 -0
  53. package/dist-lib/lib/maps-processor.server.d.ts.map +1 -0
  54. package/dist-lib/lib/maps-processor.server.js +315 -0
  55. package/dist-lib/lib/maps.functions.d.ts +186950 -0
  56. package/dist-lib/lib/maps.functions.d.ts.map +1 -0
  57. package/dist-lib/lib/maps.functions.js +63 -0
  58. package/dist-lib/lib/utils.d.ts +3 -0
  59. package/dist-lib/lib/utils.d.ts.map +1 -0
  60. package/dist-lib/lib/utils.js +5 -0
  61. package/dist-lib/lib/validationSchemas.d.ts +15 -0
  62. package/dist-lib/lib/validationSchemas.d.ts.map +1 -0
  63. package/dist-lib/lib/validationSchemas.js +25 -0
  64. package/dist-lib/styles.css +1 -0
  65. package/package.json +87 -0
  66. package/public/logo.png +0 -0
@@ -0,0 +1,92 @@
1
+ export const Constants = {
2
+ public: {
3
+ Enums: {
4
+ ai_import_status: [
5
+ "nieuw",
6
+ "verwerken",
7
+ "bevestigen",
8
+ "klaar",
9
+ "mislukt",
10
+ ],
11
+ app_role: [
12
+ "admin",
13
+ "planner",
14
+ "monteur",
15
+ "administratie",
16
+ "ai_admin",
17
+ "manager",
18
+ "warehouse",
19
+ "sales",
20
+ "developer",
21
+ "receptie",
22
+ ],
23
+ doc_layout_type: [
24
+ "pakbon",
25
+ "factuur",
26
+ "offerte",
27
+ "orderbevestiging",
28
+ "etiket",
29
+ "verzendlabel",
30
+ "productlabel",
31
+ "barcode_label",
32
+ "magazijnlijst",
33
+ "controlelijst",
34
+ "transportdocument",
35
+ "vrij",
36
+ "sticker",
37
+ "productiebon",
38
+ "veilingbon",
39
+ "afleverbrief",
40
+ "veilingbrief",
41
+ ],
42
+ doc_orientation: ["portrait", "landscape"],
43
+ exact_env: ["staging", "live"],
44
+ exact_push_status: ["pending", "sent", "error"],
45
+ itk_customer_segment: ["Business", "Private"],
46
+ itk_dynamic_field_type: ["text", "select", "date", "checkbox"],
47
+ planning_item_status: [
48
+ "gepland",
49
+ "bezig",
50
+ "afgerond",
51
+ "geannuleerd",
52
+ "concept",
53
+ "vrijgegeven",
54
+ ],
55
+ print_job_status: [
56
+ "wachtend",
57
+ "bezig",
58
+ "voltooid",
59
+ "mislukt",
60
+ "geannuleerd",
61
+ ],
62
+ printer_connection: [
63
+ "ipp",
64
+ "raw9100",
65
+ "printnode",
66
+ "cups",
67
+ "usb",
68
+ "windows",
69
+ "airprint",
70
+ "cloud",
71
+ ],
72
+ printer_kind: [
73
+ "labelprinter",
74
+ "laserprinter",
75
+ "inkjet",
76
+ "thermal",
77
+ "kantoorprinter",
78
+ "overig",
79
+ ],
80
+ quote_status: [
81
+ "concept",
82
+ "verzonden",
83
+ "bekeken",
84
+ "in_behandeling",
85
+ "geaccepteerd",
86
+ "afgewezen",
87
+ "verlopen",
88
+ "gearchiveerd",
89
+ ],
90
+ },
91
+ },
92
+ };
@@ -0,0 +1,60 @@
1
+ export declare const GOOGLE_PROVIDER = "google_maps";
2
+ export declare class GoogleCredentialUnavailableError extends Error {
3
+ constructor(message: string);
4
+ }
5
+ export interface GoogleApiKeyResult {
6
+ apiKey: string;
7
+ expiresAt: string | null;
8
+ }
9
+ /**
10
+ * Haalt de Google Maps API-key op bij Central Auth via
11
+ * POST /api/token/google_maps met body {"environment":"live"}.
12
+ * Het antwoordveld access_token bevat de API-key (geen OAuth-token).
13
+ */
14
+ export declare function fetchGoogleApiKey(): Promise<GoogleApiKeyResult>;
15
+ /** Haalt de Google Maps API-key op via de centrale auth-module. */
16
+ export declare function getGoogleAccessToken(): Promise<string>;
17
+ /** Korte, mensleesbare status voor de beheerschermen. */
18
+ export declare function getGoogleConnectionStatus(): Promise<{
19
+ connected: boolean;
20
+ reason: string | null;
21
+ }>;
22
+ export interface MapsConnectionStatus {
23
+ connected: boolean;
24
+ centralHost: string | null;
25
+ secretPresent: boolean;
26
+ accountPresent: boolean;
27
+ account: string | null;
28
+ accountStatus: string | null;
29
+ expiresAt: string | null;
30
+ reason: string | null;
31
+ }
32
+ /** Uitgebreide koppelingsstatus voor de statustab. */
33
+ export declare function getMapsConnectionStatus(): Promise<MapsConnectionStatus>;
34
+ export interface MapsDiagnosticStep {
35
+ name: string;
36
+ ok: boolean;
37
+ target: string;
38
+ httpStatus: number | null;
39
+ summary: string;
40
+ /** Gesaneerd JSON-antwoord als tekst (nooit geheimen). */
41
+ body: string | null;
42
+ code?: string | null;
43
+ hint?: string | null;
44
+ }
45
+ export interface MapsDiagnosticsReport {
46
+ measuredAt: string;
47
+ centralHost: string | null;
48
+ secretPresent: boolean;
49
+ steps: MapsDiagnosticStep[];
50
+ hints: string[];
51
+ checklist: string[];
52
+ }
53
+ export declare function collectMapsDiagnostics(probeGoogle: (stepName: string, target: string) => Promise<MapsDiagnosticStep>, probeSupabase: () => Promise<MapsDiagnosticStep>): Promise<MapsDiagnosticsReport>;
54
+ /** Lichte test-aanroep voor de statustab ("Verbinding testen"). */
55
+ export declare function testGoogleConnectionLive(): Promise<{
56
+ ok: boolean;
57
+ message: string;
58
+ detail: string | null;
59
+ }>;
60
+ //# sourceMappingURL=central-auth.server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"central-auth.server.d.ts","sourceRoot":"","sources":["../../src/lib/central-auth.server.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C,qBAAa,gCAAiC,SAAQ,KAAK;gBAC7C,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAID;;;;GAIG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAgErE;AAED,mEAAmE;AACnE,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC,CAG5D;AAGD,yDAAyD;AACzD,wBAAsB,yBAAyB,IAAI,OAAO,CAAC;IACzD,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC,CAUD;AAID,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAmBD,sDAAsD;AACtD,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAiF7E;AAID,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AA+ED,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,CAAC,EAC9E,aAAa,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,GAC/C,OAAO,CAAC,qBAAqB,CAAC,CA+KhC;AAED,mEAAmE;AACnE,wBAAsB,wBAAwB,IAAI,OAAO,CAAC;IACxD,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC,CAoBD"}
@@ -0,0 +1,439 @@
1
+ // Server-only helper: haalt de Google Maps API-key op bij de centrale
2
+ // auth-module. Vereist CENTRAL_AUTH_URL en CENTRAL_AUTH_SECRET.
3
+ // De key verlaat de server nooit.
4
+ import { listProviderAccounts, } from "@flowselections/core/server";
5
+ export const GOOGLE_PROVIDER = "google_maps";
6
+ export class GoogleCredentialUnavailableError extends Error {
7
+ constructor(message) {
8
+ super(message);
9
+ this.name = "GoogleCredentialUnavailableError";
10
+ }
11
+ }
12
+ let keyCache = null;
13
+ /**
14
+ * Haalt de Google Maps API-key op bij Central Auth via
15
+ * POST /api/token/google_maps met body {"environment":"live"}.
16
+ * Het antwoordveld access_token bevat de API-key (geen OAuth-token).
17
+ */
18
+ export async function fetchGoogleApiKey() {
19
+ const now = Date.now();
20
+ if (keyCache && keyCache.cachedUntil > now) {
21
+ return { apiKey: keyCache.apiKey, expiresAt: keyCache.expiresAt };
22
+ }
23
+ const cfg = centralConfig();
24
+ if (!cfg) {
25
+ throw new GoogleCredentialUnavailableError("Central Auth is niet geconfigureerd (CENTRAL_AUTH_URL/CENTRAL_AUTH_SECRET ontbreken).");
26
+ }
27
+ let response;
28
+ try {
29
+ response = await fetch(`${cfg.host}/api/token/${GOOGLE_PROVIDER}`, {
30
+ method: "POST",
31
+ headers: {
32
+ Authorization: `Bearer ${cfg.secret}`,
33
+ "Content-Type": "application/json",
34
+ },
35
+ body: JSON.stringify({ environment: "live" }),
36
+ });
37
+ }
38
+ catch (error) {
39
+ throw new GoogleCredentialUnavailableError(`Central Auth is niet bereikbaar: ${errSummary(error)}`);
40
+ }
41
+ if (!response.ok) {
42
+ const detail = (await response.text().catch(() => "")).slice(0, 200);
43
+ if (response.status === 404) {
44
+ throw new GoogleCredentialUnavailableError(`Provider "${GOOGLE_PROVIDER}" is niet bekend in Central Auth (HTTP 404).`);
45
+ }
46
+ if (response.status === 401 || response.status === 403) {
47
+ throw new GoogleCredentialUnavailableError("Central Auth weigert het secret van deze module (CENTRAL_AUTH_SECRET klopt niet).");
48
+ }
49
+ throw new GoogleCredentialUnavailableError(`Central Auth gaf HTTP ${response.status} terug: ${detail}`);
50
+ }
51
+ const payload = (await response.json().catch(() => null));
52
+ const apiKey = payload?.access_token ?? payload?.accessToken ?? null;
53
+ if (!apiKey) {
54
+ throw new GoogleCredentialUnavailableError("Central Auth gaf geen access_token (API-key) terug voor google_maps.");
55
+ }
56
+ const expiresAt = payload?.expires_at ?? payload?.expiresAt ?? null;
57
+ const expiryMs = expiresAt ? Date.parse(expiresAt) : Number.NaN;
58
+ const cachedUntil = Number.isNaN(expiryMs)
59
+ ? now + 5 * 60 * 1000
60
+ : Math.min(expiryMs - 60000, now + 5 * 60 * 1000);
61
+ keyCache = { apiKey, expiresAt, cachedUntil };
62
+ return { apiKey, expiresAt };
63
+ }
64
+ /** Haalt de Google Maps API-key op via de centrale auth-module. */
65
+ export async function getGoogleAccessToken() {
66
+ const { apiKey } = await fetchGoogleApiKey();
67
+ return apiKey;
68
+ }
69
+ /** Korte, mensleesbare status voor de beheerschermen. */
70
+ export async function getGoogleConnectionStatus() {
71
+ try {
72
+ await getGoogleAccessToken();
73
+ return { connected: true, reason: null };
74
+ }
75
+ catch (error) {
76
+ return {
77
+ connected: false,
78
+ reason: error instanceof Error ? error.message : "Onbekende fout",
79
+ };
80
+ }
81
+ }
82
+ function centralConfig() {
83
+ const host = process.env["CENTRAL_AUTH_URL"];
84
+ const secret = process.env["CENTRAL_AUTH_SECRET"];
85
+ if (!host || !secret)
86
+ return null;
87
+ return { host: host.replace(/\/+$/, ""), secret };
88
+ }
89
+ function firstAccount(accounts) {
90
+ return Array.isArray(accounts) && accounts.length > 0 ? accounts[0] ?? null : null;
91
+ }
92
+ function accountUsable(account) {
93
+ if (!account)
94
+ return false;
95
+ const status = (account.status ?? "").toLowerCase();
96
+ return ["active", "connected", "authorized", "ok"].includes(status);
97
+ }
98
+ /** Uitgebreide koppelingsstatus voor de statustab. */
99
+ export async function getMapsConnectionStatus() {
100
+ const cfg = centralConfig();
101
+ const base = {
102
+ connected: false,
103
+ centralHost: cfg?.host ?? null,
104
+ secretPresent: Boolean(cfg),
105
+ accountPresent: false,
106
+ account: null,
107
+ accountStatus: null,
108
+ expiresAt: null,
109
+ reason: null,
110
+ };
111
+ if (!cfg) {
112
+ return { ...base, reason: "Central Auth is niet geconfigureerd (CENTRAL_AUTH_URL/SECRET ontbreken)." };
113
+ }
114
+ // Accountinformatie ophalen.
115
+ let accounts = [];
116
+ try {
117
+ accounts = await listProviderAccounts(GOOGLE_PROVIDER);
118
+ }
119
+ catch (error) {
120
+ const fallback = error instanceof Error ? error.message : "Onbekende fout";
121
+ const probe = await probeCentralAccounts(GOOGLE_PROVIDER);
122
+ const referenceProbe = probe.reachable ? await probeCentralAccounts(REFERENCE_PROVIDER) : null;
123
+ const centralUp = referenceProbe?.reachable === true &&
124
+ referenceProbe.httpStatus !== null &&
125
+ referenceProbe.httpStatus < 500;
126
+ if (probe.httpStatus === 401 || probe.httpStatus === 403) {
127
+ return { ...base, reason: "Central Auth weigert het secret van deze module (CENTRAL_AUTH_SECRET klopt niet)." };
128
+ }
129
+ if (probe.httpStatus === 404) {
130
+ return {
131
+ ...base,
132
+ reason: "De provider google_maps is nog niet ingericht in Central Auth. Voeg google_maps daar toe en koppel een Google-account.",
133
+ };
134
+ }
135
+ if (centralUp && probe.httpStatus !== null && probe.httpStatus >= 500) {
136
+ return { ...base, reason: `Central Auth gaf een serverfout (HTTP ${probe.httpStatus}).` };
137
+ }
138
+ if (!probe.reachable) {
139
+ return { ...base, reason: `Central Auth is niet bereikbaar: ${probe.error ?? fallback}` };
140
+ }
141
+ return { ...base, reason: `Central Auth gaf een fout terug: ${fallback}` };
142
+ }
143
+ const account = firstAccount(accounts);
144
+ if (!account) {
145
+ return { ...base, reason: "Nog geen Google-account gekoppeld in Central Auth." };
146
+ }
147
+ // API-key ophalen als laatste controle.
148
+ let expiresAt = null;
149
+ try {
150
+ const key = await fetchGoogleApiKey();
151
+ expiresAt = key.expiresAt;
152
+ }
153
+ catch (error) {
154
+ const reason = error instanceof Error ? error.message : "Onbekende fout";
155
+ return {
156
+ ...base,
157
+ accountPresent: true,
158
+ account: account.accountKey,
159
+ accountStatus: account.status,
160
+ reason: `Token ophalen mislukt: ${reason}`,
161
+ };
162
+ }
163
+ return {
164
+ ...base,
165
+ connected: accountUsable(account),
166
+ accountPresent: true,
167
+ account: account.accountKey,
168
+ accountStatus: account.status,
169
+ expiresAt,
170
+ reason: accountUsable(account) ? null : `Accountstatus: ${account.status}`,
171
+ };
172
+ }
173
+ function sanitizeValue(value, depth = 0) {
174
+ if (value === null || value === undefined)
175
+ return value;
176
+ if (Array.isArray(value)) {
177
+ return depth > 4 ? "[...]" : value.slice(0, 10).map((item) => sanitizeValue(item, depth + 1));
178
+ }
179
+ if (typeof value === "object") {
180
+ if (depth > 4)
181
+ return "{...}";
182
+ const out = {};
183
+ for (const [key, inner] of Object.entries(value)) {
184
+ if (/(secret|token|password|key|credential|authorization|apikey)/i.test(key)) {
185
+ out[key] =
186
+ typeof inner === "string"
187
+ ? `«verborgen, ${inner.length} tekens»`
188
+ : inner === null || inner === undefined
189
+ ? "«leeg»"
190
+ : "«verborgen»";
191
+ continue;
192
+ }
193
+ out[key] = sanitizeValue(inner, depth + 1);
194
+ }
195
+ return out;
196
+ }
197
+ if (typeof value === "string")
198
+ return value.length > 300 ? `${value.slice(0, 300)}…` : value;
199
+ return value;
200
+ }
201
+ function bodyToText(value) {
202
+ if (value === null || value === undefined)
203
+ return null;
204
+ try {
205
+ return JSON.stringify(sanitizeValue(value), null, 2);
206
+ }
207
+ catch {
208
+ return null;
209
+ }
210
+ }
211
+ function errSummary(error) {
212
+ return error instanceof Error ? error.message.slice(0, 200) : String(error).slice(0, 200);
213
+ }
214
+ /**
215
+ * Provider waarvan bekend is dat Central Auth hem kent. Wordt alleen gebruikt
216
+ * om te bepalen of Central Auth zélf bereikbaar is.
217
+ */
218
+ const REFERENCE_PROVIDER = "2ba";
219
+ /**
220
+ * Rauwe controle-aanroep op /api/accounts/<provider>. Geeft de HTTP-status
221
+ * terug zodat we netwerkfouten, 401 en onbekende providers uit elkaar kunnen
222
+ * houden. Het secret gaat alleen de header in en wordt nooit teruggegeven.
223
+ */
224
+ async function probeCentralAccounts(provider) {
225
+ const cfg = centralConfig();
226
+ if (!cfg)
227
+ return { reachable: false, httpStatus: null, error: "Central Auth is niet geconfigureerd." };
228
+ try {
229
+ const controller = new AbortController();
230
+ const timeout = setTimeout(() => controller.abort(), 10000);
231
+ try {
232
+ const response = await fetch(`${cfg.host}/api/accounts/${encodeURIComponent(provider)}`, {
233
+ headers: { Authorization: `Bearer ${cfg.secret}` },
234
+ signal: controller.signal,
235
+ });
236
+ return { reachable: true, httpStatus: response.status, error: null };
237
+ }
238
+ finally {
239
+ clearTimeout(timeout);
240
+ }
241
+ }
242
+ catch (error) {
243
+ return { reachable: false, httpStatus: null, error: errSummary(error) };
244
+ }
245
+ }
246
+ export async function collectMapsDiagnostics(probeGoogle, probeSupabase) {
247
+ const cfg = centralConfig();
248
+ const steps = [];
249
+ const hints = [];
250
+ const checklist = [];
251
+ // Stap 1: configuratie.
252
+ steps.push({
253
+ name: "Central Auth-configuratie",
254
+ ok: Boolean(cfg),
255
+ target: "CENTRAL_AUTH_URL / CENTRAL_AUTH_SECRET",
256
+ httpStatus: null,
257
+ summary: cfg
258
+ ? `Host: ${cfg.host}`
259
+ : "CENTRAL_AUTH_URL of CENTRAL_AUTH_SECRET ontbreekt in de server-omgeving.",
260
+ body: null,
261
+ code: cfg ? null : "central_config",
262
+ hint: cfg
263
+ ? null
264
+ : "Voeg CENTRAL_AUTH_URL en CENTRAL_AUTH_SECRET toe aan de server-omgeving van deze module.",
265
+ });
266
+ if (!cfg) {
267
+ hints.push("Central Auth is niet geconfigureerd voor deze module.");
268
+ checklist.push("Voeg CENTRAL_AUTH_URL en CENTRAL_AUTH_SECRET toe aan de server-omgeving.");
269
+ return { measuredAt: new Date().toISOString(), centralHost: null, secretPresent: false, steps, hints, checklist };
270
+ }
271
+ // Stap 2: is Central Auth zelf bereikbaar? Controle op een provider waarvan
272
+ // bekend is dat Central Auth hem kent.
273
+ const reference = await probeCentralAccounts(REFERENCE_PROVIDER);
274
+ const centralReachable = reference.reachable && reference.httpStatus !== null && reference.httpStatus < 500;
275
+ steps.push({
276
+ name: "Central Auth bereikbaar",
277
+ ok: centralReachable,
278
+ target: `GET ${cfg.host}/api/accounts/${REFERENCE_PROVIDER}`,
279
+ httpStatus: reference.httpStatus,
280
+ summary: reference.reachable
281
+ ? centralReachable
282
+ ? `Central Auth antwoordt (HTTP ${reference.httpStatus}).`
283
+ : `Central Auth antwoordt met een serverfout (HTTP ${reference.httpStatus}).`
284
+ : `Central Auth is niet te bereiken: ${reference.error ?? "onbekende netwerkfout"}`,
285
+ body: null,
286
+ code: centralReachable ? null : reference.reachable ? "central_server_error" : "central_unreachable",
287
+ hint: centralReachable
288
+ ? null
289
+ : "Controleer of de Central Auth-module online is en of CENTRAL_AUTH_URL naar de juiste host wijst.",
290
+ });
291
+ // Stap 3: accounts ophalen bij Central Auth.
292
+ let accounts = [];
293
+ try {
294
+ accounts = await listProviderAccounts(GOOGLE_PROVIDER);
295
+ const account = firstAccount(accounts);
296
+ steps.push({
297
+ name: "Google-account in Central Auth",
298
+ ok: Boolean(account),
299
+ target: `GET /api/accounts/${GOOGLE_PROVIDER}`,
300
+ httpStatus: null,
301
+ summary: account
302
+ ? `Account "${account.accountKey}" met status "${account.status}".`
303
+ : "Central Auth gaf geen Google-account terug.",
304
+ body: bodyToText(accounts),
305
+ code: account ? null : "no_account",
306
+ hint: account
307
+ ? null
308
+ : "Koppel een Google-account in Central Auth (provider: google_maps) en draai de diagnose opnieuw.",
309
+ });
310
+ if (!account) {
311
+ hints.push("Er is nog geen Google-account gekoppeld in Central Auth.");
312
+ checklist.push("Koppel een Google-account in Central Auth (provider: google_maps).");
313
+ }
314
+ }
315
+ catch (error) {
316
+ const googleProbe = await probeCentralAccounts(GOOGLE_PROVIDER);
317
+ let summary;
318
+ let code;
319
+ let hint;
320
+ if (googleProbe.httpStatus === 401 || googleProbe.httpStatus === 403) {
321
+ summary = "Central Auth wijst de aanroep af: het secret klopt niet.";
322
+ code = "central_unauthorized";
323
+ hint = "Controleer CENTRAL_AUTH_SECRET in de server-omgeving van deze module.";
324
+ hints.push("CENTRAL_AUTH_SECRET wordt door Central Auth geweigerd.");
325
+ checklist.push("Zet het juiste CENTRAL_AUTH_SECRET in de server-omgeving.");
326
+ }
327
+ else if (googleProbe.httpStatus === 404) {
328
+ summary = `Provider "google_maps" is niet bekend in Central Auth (HTTP 404, unknown_provider).`;
329
+ code = "provider_not_registered";
330
+ hint =
331
+ "Richt de provider google_maps in binnen de Central Auth-module en koppel daar een Google-account met een Maps API-key.";
332
+ hints.push("De provider google_maps bestaat nog niet in Central Auth; deze module krijgt daardoor geen API-key.");
333
+ checklist.push("Richt provider google_maps in binnen de Central Auth-module en koppel een Google-account.");
334
+ }
335
+ else if (centralReachable && googleProbe.httpStatus !== null && googleProbe.httpStatus >= 500) {
336
+ summary = `Central Auth gaf een serverfout (HTTP ${googleProbe.httpStatus}).`;
337
+ code = "central_server_error";
338
+ hint = "Bekijk de logs van de Central Auth-module; de aanvraag liep daar vast.";
339
+ hints.push("Central Auth gaf een serverfout terug.");
340
+ }
341
+ else if (!googleProbe.reachable) {
342
+ summary = `Central Auth niet bereikbaar: ${googleProbe.error ?? errSummary(error)}`;
343
+ code = "central_unreachable";
344
+ hint = "Controleer of Central Auth online is en of CENTRAL_AUTH_URL juist is.";
345
+ hints.push("Central Auth is niet bereikbaar.");
346
+ checklist.push("Controleer CENTRAL_AUTH_URL en of de Central Auth-module online is.");
347
+ }
348
+ else {
349
+ summary = errSummary(error);
350
+ code = "central_error";
351
+ hint = "Controleer de Central Auth-module en draai de diagnose opnieuw.";
352
+ hints.push("Central Auth gaf een onverwachte fout terug.");
353
+ }
354
+ steps.push({
355
+ name: "Google-account in Central Auth",
356
+ ok: false,
357
+ target: `GET /api/accounts/${GOOGLE_PROVIDER}`,
358
+ httpStatus: googleProbe.httpStatus,
359
+ summary,
360
+ body: null,
361
+ code,
362
+ hint,
363
+ });
364
+ return { measuredAt: new Date().toISOString(), centralHost: cfg.host, secretPresent: true, steps, hints, checklist };
365
+ }
366
+ // Stap 4: API-key ophalen.
367
+ let tokenOk = false;
368
+ try {
369
+ const { expiresAt } = await fetchGoogleApiKey();
370
+ tokenOk = true;
371
+ steps.push({
372
+ name: "Google Maps API-key ophalen",
373
+ ok: true,
374
+ target: `POST /api/token/${GOOGLE_PROVIDER} {"environment":"live"}`,
375
+ httpStatus: 200,
376
+ summary: expiresAt
377
+ ? `API-key ontvangen, geldig tot ${expiresAt}.`
378
+ : "API-key ontvangen van Central Auth.",
379
+ body: null,
380
+ });
381
+ }
382
+ catch (error) {
383
+ steps.push({
384
+ name: "Google Maps API-key ophalen",
385
+ ok: false,
386
+ target: `POST /api/token/${GOOGLE_PROVIDER} {"environment":"live"}`,
387
+ httpStatus: null,
388
+ summary: `API-key ophalen mislukt: ${errSummary(error)}`,
389
+ body: null,
390
+ code: "key_unavailable",
391
+ hint: "Controleer of het google_maps-account in Central Auth actief is en een geldige Maps API-key bevat.",
392
+ });
393
+ hints.push("De Google Maps API-key kon niet worden opgehaald via Central Auth.");
394
+ checklist.push("Verifieer in Central Auth dat het google_maps-account actief is en een geldige API-key heeft.");
395
+ }
396
+ // Stappen 4 & 5: Google-aanroepen (alleen als token gelukt is).
397
+ if (tokenOk) {
398
+ steps.push(await probeGoogle("Google Geocoding-test", "POST https://places.googleapis.com/v1/places:searchText"));
399
+ steps.push(await probeGoogle("Google Routes-test", "POST https://routes.googleapis.com/distanceMatrix/v2:computeRouteMatrix"));
400
+ }
401
+ // Stap 6: Supabase-toegang.
402
+ steps.push(await probeSupabase());
403
+ // Hints afleiden uit de Google-stappen.
404
+ for (const step of steps) {
405
+ if (!step.ok && step.hint && !hints.includes(step.hint))
406
+ hints.push(step.hint);
407
+ }
408
+ return {
409
+ measuredAt: new Date().toISOString(),
410
+ centralHost: cfg.host,
411
+ secretPresent: true,
412
+ steps,
413
+ hints,
414
+ checklist,
415
+ };
416
+ }
417
+ /** Lichte test-aanroep voor de statustab ("Verbinding testen"). */
418
+ export async function testGoogleConnectionLive() {
419
+ try {
420
+ const { geocodeAddress } = await import("./google-maps.server");
421
+ const result = await geocodeAddress("Damrak 70, Amsterdam");
422
+ if (!result) {
423
+ return { ok: false, message: "Google gaf geen adresresultaat terug.", detail: null };
424
+ }
425
+ return {
426
+ ok: true,
427
+ message: `Verbinding werkt — Google gaf "${result.formattedAddress}" terug.`,
428
+ detail: null,
429
+ };
430
+ }
431
+ catch (error) {
432
+ const reason = error instanceof Error ? error.message : String(error);
433
+ return {
434
+ ok: false,
435
+ message: "Verbinding testen is niet gelukt.",
436
+ detail: reason.slice(0, 300),
437
+ };
438
+ }
439
+ }
@@ -0,0 +1,22 @@
1
+ export interface GeocodeResult {
2
+ formattedAddress: string;
3
+ lat: number;
4
+ lng: number;
5
+ placeId: string;
6
+ }
7
+ export interface LatLng {
8
+ lat: number;
9
+ lng: number;
10
+ }
11
+ export interface MatrixElement {
12
+ originIndex: number;
13
+ destinationIndex: number;
14
+ durationSec: number | null;
15
+ distanceM: number | null;
16
+ status: "ok" | "unreachable";
17
+ }
18
+ /** Zet één adres om naar coördinaten via Places Text Search. */
19
+ export declare function geocodeAddress(rawAddress: string): Promise<GeocodeResult | null>;
20
+ /** Reistijdmatrix (max 25x25 elementen per aanroep). */
21
+ export declare function computeRouteMatrix(origins: LatLng[], destinations: LatLng[], mode?: string): Promise<MatrixElement[]>;
22
+ //# sourceMappingURL=google-maps.server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google-maps.server.d.ts","sourceRoot":"","sources":["../../src/lib/google-maps.server.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,aAAa;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,IAAI,GAAG,aAAa,CAAC;CAC9B;AAyBD,gEAAgE;AAChE,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAwB/B;AASD,wDAAwD;AACxD,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EAAE,EACjB,YAAY,EAAE,MAAM,EAAE,EACtB,IAAI,SAAU,GACb,OAAO,CAAC,aAAa,EAAE,CAAC,CAiC1B"}