@open-xamu-co/firebase-nuxt 2.0.0-next.1 → 2.0.0-next.11
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 +98 -0
- package/README.md +1 -5
- package/dist/module.json +1 -1
- package/dist/module.mjs +35 -40
- package/dist/runtime/client/types/entities/logs.d.ts +10 -1
- package/dist/runtime/client/types/entities/user.d.ts +1 -1
- package/dist/runtime/client/utils/locale.d.ts +6 -0
- package/dist/runtime/composables/firestore/write.d.ts +4 -4
- package/dist/runtime/composables/firestore/write.js +12 -8
- package/dist/runtime/composables/store/session.d.ts +3 -3
- package/dist/runtime/composables/store/session.js +3 -7
- package/dist/runtime/composables/useQuery.d.ts +5 -2
- package/dist/runtime/composables/useQuery.js +1 -6
- package/dist/runtime/functions/types/entities/instance.d.ts +7 -7
- package/dist/runtime/functions/types/entities/logs.d.ts +26 -0
- package/dist/runtime/functions/utils/event.d.ts +1 -1
- package/dist/runtime/functions/utils/event.js +13 -4
- package/dist/runtime/functions/utils/logger.d.ts +4 -0
- package/dist/runtime/functions/utils/logger.js +24 -1
- package/dist/runtime/functions/utils/search.d.ts +21 -1
- package/dist/runtime/functions/utils/search.js +20 -10
- package/dist/runtime/server/api/{all-collection-document.get.d.ts → all-collection-document.d.ts} +1 -1
- package/dist/runtime/server/api/all-collection-document.js +75 -0
- package/dist/runtime/server/api/{all-collection.get.d.ts → all-collection.d.ts} +1 -1
- package/dist/runtime/server/api/all-collection.js +85 -0
- package/dist/runtime/server/api/{media.get.d.ts → media.d.ts} +1 -1
- package/dist/runtime/server/api/{media.get.js → media.js} +20 -4
- package/dist/runtime/server/middleware/1.context.js +5 -17
- package/dist/runtime/server/utils/cache.d.ts +3 -1
- package/dist/runtime/server/utils/cache.js +13 -6
- package/dist/runtime/server/utils/environment.d.ts +0 -5
- package/dist/runtime/server/utils/environment.js +0 -1
- package/dist/runtime/server/utils/firestore.d.ts +1 -1
- package/dist/runtime/server/utils/firestore.js +7 -10
- package/dist/runtime/server/utils/instance.js +3 -3
- package/package.json +11 -10
- package/dist/runtime/server/api/all-collection-document.get.js +0 -56
- package/dist/runtime/server/api/all-collection.get.js +0 -67
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,103 @@
|
|
|
1
1
|
Firebase nuxt
|
|
2
2
|
|
|
3
|
+
# [2.0.0-next.11](https://github.com/xamu-co/firebase-nuxt/compare/v2.0.0-next.10...v2.0.0-next.11) (2026-04-03)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* bump for editor fixes ([061e550](https://github.com/xamu-co/firebase-nuxt/commit/061e550052d42068c03ef25344aebb706ea29acd))
|
|
9
|
+
|
|
10
|
+
# [2.0.0-next.10](https://github.com/xamu-co/firebase-nuxt/compare/v2.0.0-next.9...v2.0.0-next.10) (2026-01-27)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* define default cache header on helper handler ([48bcfab](https://github.com/xamu-co/firebase-nuxt/commit/48bcfab258e054179524824b67b89745a757eb60))
|
|
16
|
+
* remove unsafe csurf module ([61c0487](https://github.com/xamu-co/firebase-nuxt/commit/61c0487a39ea7569e17468d64974dd8a1e8bd16c))
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### BREAKING CHANGES
|
|
20
|
+
|
|
21
|
+
* removed csurf module and related helpers
|
|
22
|
+
|
|
23
|
+
# [2.0.0-next.9](https://github.com/xamu-co/firebase-nuxt/compare/v2.0.0-next.8...v2.0.0-next.9) (2026-01-21)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### Bug Fixes
|
|
27
|
+
|
|
28
|
+
* bump for editor fix ([46eec97](https://github.com/xamu-co/firebase-nuxt/commit/46eec975e7706188e883b375b314dfd020bf1968))
|
|
29
|
+
|
|
30
|
+
# [2.0.0-next.8](https://github.com/xamu-co/firebase-nuxt/compare/v2.0.0-next.7...v2.0.0-next.8) (2026-01-21)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
### Features
|
|
34
|
+
|
|
35
|
+
* bump for useMarkdown ([8c7cfd2](https://github.com/xamu-co/firebase-nuxt/commit/8c7cfd28e750a940aa8705ac35308312c4cdc41e))
|
|
36
|
+
|
|
37
|
+
# [2.0.0-next.7](https://github.com/xamu-co/firebase-nuxt/compare/v2.0.0-next.6...v2.0.0-next.7) (2026-01-20)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
### Bug Fixes
|
|
41
|
+
|
|
42
|
+
* configurable default on session store actions ([117ce2e](https://github.com/xamu-co/firebase-nuxt/commit/117ce2e206563f4aa14eba7d427c9432cbfb7705))
|
|
43
|
+
|
|
44
|
+
# [2.0.0-next.6](https://github.com/xamu-co/firebase-nuxt/compare/v2.0.0-next.5...v2.0.0-next.6) (2026-01-20)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
### Features
|
|
48
|
+
|
|
49
|
+
* generate weighted search indexes ([36fdabc](https://github.com/xamu-co/firebase-nuxt/commit/36fdabc0ed5060813f2abf3aa748f023d9d3bb8f))
|
|
50
|
+
|
|
51
|
+
# [2.0.0-next.5](https://github.com/xamu-co/firebase-nuxt/compare/v2.0.0-next.4...v2.0.0-next.5) (2026-01-20)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
### Bug Fixes
|
|
55
|
+
|
|
56
|
+
* bump for mapNodes priority ([08df299](https://github.com/xamu-co/firebase-nuxt/commit/08df29970297b82830253dfdd1920a1e9afd8f13))
|
|
57
|
+
|
|
58
|
+
# [2.0.0-next.4](https://github.com/xamu-co/firebase-nuxt/compare/v2.0.0-next.3...v2.0.0-next.4) (2026-01-20)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
### Bug Fixes
|
|
62
|
+
|
|
63
|
+
* crash firestore method if missing instance ([4d29aec](https://github.com/xamu-co/firebase-nuxt/commit/4d29aece4c13e80070e97aa63ee8d8609755ef4b))
|
|
64
|
+
* preserve creation date ([7a3c2d2](https://github.com/xamu-co/firebase-nuxt/commit/7a3c2d21a3ef82cc6d736f918d30f3086c4f6fae))
|
|
65
|
+
* soundex algorithm as param ([2fceb8d](https://github.com/xamu-co/firebase-nuxt/commit/2fceb8d3097e92dee91baae642a0c88a3c3e061a))
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
### Features
|
|
69
|
+
|
|
70
|
+
* bump for code editor ([838f5b3](https://github.com/xamu-co/firebase-nuxt/commit/838f5b327c3dd4681cb3d68200ec4aa1be9a6afe))
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
### BREAKING CHANGES
|
|
74
|
+
|
|
75
|
+
* onDelete >>> onDeleted
|
|
76
|
+
|
|
77
|
+
# [2.0.0-next.3](https://github.com/xamu-co/firebase-nuxt/compare/v2.0.0-next.2...v2.0.0-next.3) (2026-01-16)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
### Bug Fixes
|
|
81
|
+
|
|
82
|
+
* bump dependencies for h3 vurnerability ([30f8565](https://github.com/xamu-co/firebase-nuxt/commit/30f85650c08814838bf967a4f524d32f245f1f45))
|
|
83
|
+
|
|
84
|
+
# [2.0.0-next.2](https://github.com/xamu-co/firebase-nuxt/compare/v2.0.0-next.1...v2.0.0-next.2) (2026-01-15)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
### Bug Fixes
|
|
88
|
+
|
|
89
|
+
* prevent no content on head responses ([a16a768](https://github.com/xamu-co/firebase-nuxt/commit/a16a7682d3fb322bafda64177f5d57541069beac))
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
### Features
|
|
93
|
+
|
|
94
|
+
* accept head & options request ([2822f2f](https://github.com/xamu-co/firebase-nuxt/commit/2822f2ffeb27cc5b6034cb4fe131ae20ae0bde99))
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
### BREAKING CHANGES
|
|
98
|
+
|
|
99
|
+
* less args at resolveServerDocumentRefs
|
|
100
|
+
|
|
3
101
|
# [2.0.0-next.1](https://github.com/xamu-co/firebase-nuxt/compare/v1.2.0-next.2...v2.0.0-next.1) (2026-01-13)
|
|
4
102
|
|
|
5
103
|
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Xamu nuxt firebase module
|
|
2
2
|
|
|
3
|
-
Powered by Nuxt.js
|
|
3
|
+
Powered by [Nuxt.js](https://nuxt.com) & [Xamu UI](https://github.com/xamu-co/ui)
|
|
4
4
|
|
|
5
5
|
## Prerequisites
|
|
6
6
|
|
|
@@ -57,10 +57,6 @@ F_CLIENT_EMAIL=""
|
|
|
57
57
|
# App check, site key, public
|
|
58
58
|
RECAPTCHA_ENTERPRISE_SITE_KEY=
|
|
59
59
|
|
|
60
|
-
# CSRF protection (32 bytes)
|
|
61
|
-
# By default csurf uses `crypto.randomBytes(22).toString("base64")`
|
|
62
|
-
CSURF_SECRET=
|
|
63
|
-
|
|
64
60
|
# Project
|
|
65
61
|
ORIGIN=
|
|
66
62
|
COUNTRIES_API=
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineNuxtModule, createResolver, addPlugin, addImportsDir, addComponentsDir, addServerTemplate, addServerHandler } from '@nuxt/kit';
|
|
2
2
|
import { locale } from '../dist/runtime/client/utils/locale.js';
|
|
3
|
-
import {
|
|
3
|
+
import { debugNuxt, port, publicRuntimeConfig } from '../dist/runtime/server/utils/environment.js';
|
|
4
4
|
|
|
5
5
|
const module$1 = defineNuxtModule({
|
|
6
6
|
meta: {
|
|
@@ -84,50 +84,45 @@ const module$1 = defineNuxtModule({
|
|
|
84
84
|
middleware: true,
|
|
85
85
|
handler: resolve(runtimePath, "server/middleware/1.context")
|
|
86
86
|
});
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
87
|
+
const methods = ["get", "head", "options"];
|
|
88
|
+
methods.forEach((method) => {
|
|
89
|
+
if (moduleOptions.media) {
|
|
90
|
+
addServerHandler({
|
|
91
|
+
method,
|
|
92
|
+
route: "/api/media/**:path",
|
|
93
|
+
handler: resolve(runtimePath, "server/api/media")
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
if (moduleOptions.readCollection) {
|
|
97
|
+
addServerHandler({
|
|
98
|
+
method,
|
|
99
|
+
route: "/api/all/:collectionId",
|
|
100
|
+
handler: resolve(runtimePath, "server/api/all-collection")
|
|
101
|
+
});
|
|
102
|
+
addServerHandler({
|
|
103
|
+
method,
|
|
104
|
+
route: "/api/all/:collectionId/:documentId",
|
|
105
|
+
handler: resolve(runtimePath, "server/api/all-collection-document")
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
if (moduleOptions.readInstanceCollection) {
|
|
109
|
+
addServerHandler({
|
|
110
|
+
method,
|
|
111
|
+
route: "/api/instance/all/:collectionId",
|
|
112
|
+
handler: resolve(runtimePath, "server/api/all-collection")
|
|
113
|
+
});
|
|
114
|
+
addServerHandler({
|
|
115
|
+
method,
|
|
116
|
+
route: "/api/instance/all/:collectionId/:documentId",
|
|
117
|
+
handler: resolve(runtimePath, "server/api/all-collection-document")
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
});
|
|
118
121
|
},
|
|
119
122
|
moduleDependencies() {
|
|
120
123
|
const { resolve } = createResolver(import.meta.url);
|
|
121
124
|
const runtimePath = resolve("./runtime");
|
|
122
125
|
return {
|
|
123
|
-
"nuxt-csurf": {
|
|
124
|
-
version: ">=1.6.5",
|
|
125
|
-
defaults: {
|
|
126
|
-
addCsrfTokenToEventCtx: true,
|
|
127
|
-
// Run server side
|
|
128
|
-
encryptSecret: csurfSecret.value() || void 0
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
126
|
"@open-xamu-co/ui-nuxt": {
|
|
132
127
|
version: ">=4.0.0-next.4",
|
|
133
128
|
defaults: {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { DocumentReference } from "firebase/firestore";
|
|
2
|
+
import type { LogData, OffenderData } from "../../../functions/types/index.js";
|
|
2
3
|
import type { FromData } from "./base.js";
|
|
3
4
|
import type { GetSharedRef } from "./user.js";
|
|
4
5
|
/** @output Log */
|
|
@@ -7,3 +8,11 @@ export interface Log extends FromData<LogData> {
|
|
|
7
8
|
/** @input Omit automation */
|
|
8
9
|
export interface LogRef extends GetSharedRef<Log> {
|
|
9
10
|
}
|
|
11
|
+
/** @output Offender */
|
|
12
|
+
export interface Offender extends FromData<OffenderData> {
|
|
13
|
+
lastLog?: Log;
|
|
14
|
+
}
|
|
15
|
+
/** @input Omit automation */
|
|
16
|
+
export interface OffenderRef extends GetSharedRef<Offender> {
|
|
17
|
+
lastLogRef?: DocumentReference<LogData>;
|
|
18
|
+
}
|
|
@@ -9,7 +9,7 @@ import type { Instance, SharedDocument } from "./instance.js";
|
|
|
9
9
|
* Removed properties are not required or are part of automation
|
|
10
10
|
*/
|
|
11
11
|
export type GetSharedRef<T extends SharedDocument, O extends keyof T = never> = {
|
|
12
|
-
[K in keyof FromData<Omit<T,
|
|
12
|
+
[K in keyof FromData<Omit<T, O>> as K extends `${string}At` ? never : K]: FromData<Omit<T, O>>[K];
|
|
13
13
|
} & {
|
|
14
14
|
createdByRef?: DocumentReference | FieldValue;
|
|
15
15
|
updatedByRef?: DocumentReference | FieldValue;
|
|
@@ -109,6 +109,12 @@ export declare const locale: {
|
|
|
109
109
|
form_invalid_data: string;
|
|
110
110
|
form_no_values: string;
|
|
111
111
|
form_new_value: string;
|
|
112
|
+
form_editor_preview: string;
|
|
113
|
+
form_editor_see_preview: string;
|
|
114
|
+
form_editor_bold: string;
|
|
115
|
+
form_editor_italic: string;
|
|
116
|
+
form_editor_link: string;
|
|
117
|
+
form_editor_link_add_url: string;
|
|
112
118
|
table_see_values: string;
|
|
113
119
|
table_see_name: string;
|
|
114
120
|
table_hide_name: string;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { DocumentReference } from "firebase/firestore";
|
|
2
2
|
import type { iNodeFnResponseStream } from "@open-xamu-co/ui-common-types";
|
|
3
|
-
import type { GetRef, SharedDocument, FirebaseDocument, iSnapshotConfig } from "../../client/types/index.js";
|
|
3
|
+
import type { GetRef, SharedDocument, FirebaseDocument, iSnapshotConfig, FromData } from "../../client/types/index.js";
|
|
4
4
|
interface iUseDocumentOptions extends iSnapshotConfig {
|
|
5
5
|
omitLoggings?: boolean;
|
|
6
6
|
}
|
|
7
7
|
/** Creates document with the given values */
|
|
8
|
-
export declare function useDocumentCreate<Vgr extends GetRef<
|
|
8
|
+
export declare function useDocumentCreate<Vgr extends GetRef<SharedDocument>, V extends FromData<Vgr> = FromData<Vgr>>(collectionPath: string, partialRef: Vgr, createdCallback?: (ref: DocumentReference<Vgr, V>) => Promise<void> | void, { omitLoggings, ...config }?: iUseDocumentOptions): Promise<iNodeFnResponseStream<V>>;
|
|
9
9
|
/**
|
|
10
10
|
* Updates a given document in Firestore.
|
|
11
11
|
*
|
|
@@ -13,9 +13,9 @@ export declare function useDocumentCreate<Vgr extends GetRef<V>, V extends Fireb
|
|
|
13
13
|
* @param partialRef - The partial data to update the document with.
|
|
14
14
|
* @returns A boolean promise.
|
|
15
15
|
*/
|
|
16
|
-
export declare function useDocumentUpdate<Vgr extends GetRef<
|
|
16
|
+
export declare function useDocumentUpdate<Vgr extends GetRef<SharedDocument>, V extends FromData<Vgr> = FromData<Vgr>>(node: SharedDocument, middleRef?: Partial<Vgr>, { omitLoggings, ...config }?: iUseDocumentOptions): Promise<iNodeFnResponseStream<V>>;
|
|
17
17
|
/** Clones given document */
|
|
18
|
-
export declare function useDocumentClone<Vgr extends GetRef<
|
|
18
|
+
export declare function useDocumentClone<Vgr extends GetRef<SharedDocument>, V extends FromData<Vgr> = FromData<Vgr>>(node: SharedDocument, middleRef?: Partial<Vgr>, { omitLoggings, ...config }?: iUseDocumentOptions): Promise<iNodeFnResponseStream<V>>;
|
|
19
19
|
/** Deletes given document */
|
|
20
20
|
export declare function useDocumentDelete<T extends FirebaseDocument = FirebaseDocument>(node: SharedDocument, { omitLoggings }?: iUseDocumentOptions): Promise<iNodeFnResponseStream<T>>;
|
|
21
21
|
export {};
|
|
@@ -13,10 +13,11 @@ import { getDocumentId } from "../../client/utils/resolver.js";
|
|
|
13
13
|
import { TimedPromise } from "../../server/utils/guards.js";
|
|
14
14
|
import { useAppLogger, useInstanceStore, useNuxtApp, useSessionStore } from "#imports";
|
|
15
15
|
export async function useDocumentCreate(collectionPath, partialRef, createdCallback, { omitLoggings, ...config } = { omitLoggings: false, level: 0 }) {
|
|
16
|
-
const { $clientFirestore, $resolveClientRefs } = useNuxtApp();
|
|
17
|
-
if (!collectionPath || !$clientFirestore) throw new Error("Collection path is required");
|
|
18
16
|
const SESSION = useSessionStore();
|
|
19
17
|
const INSTANCE = useInstanceStore();
|
|
18
|
+
const { $clientFirestore, $resolveClientRefs } = useNuxtApp();
|
|
19
|
+
if (!collectionPath || !$clientFirestore) throw new Error("Collection path is required");
|
|
20
|
+
if (!INSTANCE) throw new Error("Missing instance");
|
|
20
21
|
const collRef = collection($clientFirestore, collectionPath);
|
|
21
22
|
if (collectionPath === "users") {
|
|
22
23
|
const instanceRef = doc($clientFirestore, INSTANCE.id);
|
|
@@ -90,10 +91,11 @@ export async function useDocumentCreate(collectionPath, partialRef, createdCallb
|
|
|
90
91
|
}
|
|
91
92
|
}
|
|
92
93
|
export async function useDocumentUpdate(node, middleRef = {}, { omitLoggings, ...config } = { omitLoggings: false, level: 0 }) {
|
|
93
|
-
const { $clientFirestore, $resolveClientRefs } = useNuxtApp();
|
|
94
|
-
if (!node.id || !$clientFirestore) throw new Error("Document id is required");
|
|
95
94
|
const SESSION = useSessionStore();
|
|
96
95
|
const INSTANCE = useInstanceStore();
|
|
96
|
+
const { $clientFirestore, $resolveClientRefs } = useNuxtApp();
|
|
97
|
+
if (!node.id || !$clientFirestore) throw new Error("Document id is required");
|
|
98
|
+
if (!INSTANCE) throw new Error("Missing instance");
|
|
97
99
|
const docRef = doc($clientFirestore, node.id || "");
|
|
98
100
|
const partialRef = middleRef;
|
|
99
101
|
const lastUpdatedAt = node.updatedAt ? new Date(node.updatedAt).getTime() : 0;
|
|
@@ -158,10 +160,11 @@ export async function useDocumentUpdate(node, middleRef = {}, { omitLoggings, ..
|
|
|
158
160
|
}
|
|
159
161
|
}
|
|
160
162
|
export async function useDocumentClone(node, middleRef = {}, { omitLoggings, ...config } = { omitLoggings: false, level: 0 }) {
|
|
161
|
-
const { $clientFirestore, $resolveClientRefs } = useNuxtApp();
|
|
162
|
-
if (!node.id || !$clientFirestore) throw new Error("Document id is required");
|
|
163
163
|
const SESSION = useSessionStore();
|
|
164
164
|
const INSTANCE = useInstanceStore();
|
|
165
|
+
const { $clientFirestore, $resolveClientRefs } = useNuxtApp();
|
|
166
|
+
if (!node.id || !$clientFirestore) throw new Error("Document id is required");
|
|
167
|
+
if (!INSTANCE) throw new Error("Missing instance");
|
|
165
168
|
const docRef = doc($clientFirestore, node.id);
|
|
166
169
|
const partialRef = middleRef;
|
|
167
170
|
const source = (await getDoc(docRef)).data();
|
|
@@ -233,10 +236,11 @@ export async function useDocumentClone(node, middleRef = {}, { omitLoggings, ...
|
|
|
233
236
|
}
|
|
234
237
|
}
|
|
235
238
|
export async function useDocumentDelete(node, { omitLoggings } = { omitLoggings: false, level: 0 }) {
|
|
236
|
-
const { $clientFirestore } = useNuxtApp();
|
|
237
|
-
if (!node.id || !$clientFirestore) throw new Error("Document id is required");
|
|
238
239
|
const SESSION = useSessionStore();
|
|
239
240
|
const INSTANCE = useInstanceStore();
|
|
241
|
+
const { $clientFirestore } = useNuxtApp();
|
|
242
|
+
if (!node.id || !$clientFirestore) throw new Error("Document id is required");
|
|
243
|
+
if (!INSTANCE) throw new Error("Missing instance");
|
|
240
244
|
const docRef = doc($clientFirestore, node.id);
|
|
241
245
|
const memberId = getDocumentId(SESSION.path);
|
|
242
246
|
const memberPath = `${INSTANCE.id}/members/${memberId}`;
|
|
@@ -15,7 +15,7 @@ export declare const useSessionStore: import("pinia").StoreDefinition<"session",
|
|
|
15
15
|
path: import("vue").ComputedRef<string>;
|
|
16
16
|
setUser: ({ createdAt, updatedAt, ...userData }: User, token: string) => void;
|
|
17
17
|
unsetSession: (expiredToken?: boolean) => void;
|
|
18
|
-
logout: (clientAuth?: Auth) => Promise<void>;
|
|
18
|
+
logout: (clientAuth?: Auth, unsetSessionFn?: (expiredToken?: boolean) => void) => Promise<void>;
|
|
19
19
|
remove: (clientAuth?: Auth) => Promise<void>;
|
|
20
20
|
}, "user" | "token" | "expiredToken">, Pick<{
|
|
21
21
|
token: import("#app").CookieRef<string | null>;
|
|
@@ -24,7 +24,7 @@ export declare const useSessionStore: import("pinia").StoreDefinition<"session",
|
|
|
24
24
|
path: import("vue").ComputedRef<string>;
|
|
25
25
|
setUser: ({ createdAt, updatedAt, ...userData }: User, token: string) => void;
|
|
26
26
|
unsetSession: (expiredToken?: boolean) => void;
|
|
27
|
-
logout: (clientAuth?: Auth) => Promise<void>;
|
|
27
|
+
logout: (clientAuth?: Auth, unsetSessionFn?: (expiredToken?: boolean) => void) => Promise<void>;
|
|
28
28
|
remove: (clientAuth?: Auth) => Promise<void>;
|
|
29
29
|
}, "path">, Pick<{
|
|
30
30
|
token: import("#app").CookieRef<string | null>;
|
|
@@ -33,6 +33,6 @@ export declare const useSessionStore: import("pinia").StoreDefinition<"session",
|
|
|
33
33
|
path: import("vue").ComputedRef<string>;
|
|
34
34
|
setUser: ({ createdAt, updatedAt, ...userData }: User, token: string) => void;
|
|
35
35
|
unsetSession: (expiredToken?: boolean) => void;
|
|
36
|
-
logout: (clientAuth?: Auth) => Promise<void>;
|
|
36
|
+
logout: (clientAuth?: Auth, unsetSessionFn?: (expiredToken?: boolean) => void) => Promise<void>;
|
|
37
37
|
remove: (clientAuth?: Auth) => Promise<void>;
|
|
38
38
|
}, "remove" | "setUser" | "unsetSession" | "logout">>;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { deleteUser } from "firebase/auth";
|
|
2
2
|
import { defineStore, skipHydrate } from "pinia";
|
|
3
3
|
import { computed } from "vue";
|
|
4
|
-
import { getDocumentId } from "../../client/utils/resolver.js";
|
|
5
4
|
import { useCookie, useRuntimeConfig, useSwal } from "#imports";
|
|
6
5
|
const cookieOptionsDefaults = {
|
|
7
6
|
sameSite: "strict",
|
|
@@ -28,10 +27,7 @@ export const useSessionStore = defineStore("session", () => {
|
|
|
28
27
|
partitioned: false,
|
|
29
28
|
default: () => void 0
|
|
30
29
|
});
|
|
31
|
-
const path = computed(() =>
|
|
32
|
-
const id = user.value?.id;
|
|
33
|
-
return id ? `users/${getDocumentId(id)}` : "";
|
|
34
|
-
});
|
|
30
|
+
const path = computed(() => user.value?.id || "");
|
|
35
31
|
function setToken(newToken, newExpiredToken = false) {
|
|
36
32
|
token.value = newToken || null;
|
|
37
33
|
expiredToken.value = newExpiredToken;
|
|
@@ -44,7 +40,7 @@ export const useSessionStore = defineStore("session", () => {
|
|
|
44
40
|
setToken("", expiredToken2);
|
|
45
41
|
user.value = void 0;
|
|
46
42
|
}
|
|
47
|
-
async function logout(clientAuth) {
|
|
43
|
+
async function logout(clientAuth, unsetSessionFn = unsetSession) {
|
|
48
44
|
if (import.meta.server) return;
|
|
49
45
|
const Swal = useSwal();
|
|
50
46
|
const { value } = await Swal.firePrevent({
|
|
@@ -52,7 +48,7 @@ export const useSessionStore = defineStore("session", () => {
|
|
|
52
48
|
text: "\xBFEsta seguro de querer cerrar sesion?"
|
|
53
49
|
});
|
|
54
50
|
if (value) {
|
|
55
|
-
|
|
51
|
+
unsetSessionFn();
|
|
56
52
|
await clientAuth?.signOut();
|
|
57
53
|
window.location.href = "/";
|
|
58
54
|
}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import type { NitroFetchOptions, NitroFetchRequest } from "nitropack";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Inject auth headers and refresh token
|
|
4
|
+
*
|
|
5
|
+
* @param baseOptions
|
|
6
|
+
* @returns
|
|
4
7
|
*/
|
|
5
|
-
export declare function
|
|
8
|
+
export declare function getQueryOptions<R extends NitroFetchRequest = NitroFetchRequest>(baseOptions?: NitroFetchOptions<R>): Promise<NitroFetchOptions<R>>;
|
|
6
9
|
/**
|
|
7
10
|
* Fetch wrapper
|
|
8
11
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useRequestHeaders, useNuxtApp, useRuntimeConfig, useSessionStore } from "#imports";
|
|
2
|
-
async function getQueryOptions(baseOptions) {
|
|
2
|
+
export async function getQueryOptions(baseOptions) {
|
|
3
3
|
const SESSION = useSessionStore();
|
|
4
4
|
const { $clientAuth } = useNuxtApp();
|
|
5
5
|
const { cache } = useRuntimeConfig().public;
|
|
@@ -22,11 +22,6 @@ async function getQueryOptions(baseOptions) {
|
|
|
22
22
|
}
|
|
23
23
|
return { credentials: "same-origin", ...options, query, headers };
|
|
24
24
|
}
|
|
25
|
-
export async function useCsrfQuery(url, baseOptions) {
|
|
26
|
-
const { $csrfFetch } = useNuxtApp();
|
|
27
|
-
const { responseType, ...options } = await getQueryOptions(baseOptions);
|
|
28
|
-
return $csrfFetch(url, options);
|
|
29
|
-
}
|
|
30
25
|
export async function useQuery(url, baseOptions) {
|
|
31
26
|
const options = await getQueryOptions(baseOptions);
|
|
32
27
|
return $fetch(url, options);
|
|
@@ -30,6 +30,12 @@ export interface RootData extends InstanceData {
|
|
|
30
30
|
/** @example "Xamu" */
|
|
31
31
|
poweredBy?: string;
|
|
32
32
|
}
|
|
33
|
+
export interface InstanceDataConfig extends FirebaseData {
|
|
34
|
+
/**
|
|
35
|
+
* When tenants are enabled, domains are required
|
|
36
|
+
*/
|
|
37
|
+
domains?: string[];
|
|
38
|
+
}
|
|
33
39
|
/**
|
|
34
40
|
* App instance
|
|
35
41
|
*
|
|
@@ -46,13 +52,7 @@ export interface InstanceData extends SharedData {
|
|
|
46
52
|
* @automated
|
|
47
53
|
*/
|
|
48
54
|
url?: string;
|
|
49
|
-
config?:
|
|
50
|
-
[key: string]: any;
|
|
51
|
-
/**
|
|
52
|
-
* When tenants are enabled, domains are required
|
|
53
|
-
*/
|
|
54
|
-
domains?: string[];
|
|
55
|
-
};
|
|
55
|
+
config?: InstanceDataConfig;
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
58
58
|
* Firebase log
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DocumentReference } from "firebase-admin/firestore";
|
|
1
2
|
import type { FirebaseData } from "./base.js";
|
|
2
3
|
/** General log entity */
|
|
3
4
|
export interface LogData extends FirebaseData {
|
|
@@ -13,3 +14,28 @@ export interface LogData extends FirebaseData {
|
|
|
13
14
|
*/
|
|
14
15
|
internal?: boolean;
|
|
15
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Offender entity
|
|
19
|
+
*
|
|
20
|
+
* Keep track of abbussive requests
|
|
21
|
+
*/
|
|
22
|
+
export interface OffenderData extends FirebaseData {
|
|
23
|
+
/** IP address */
|
|
24
|
+
ip?: string;
|
|
25
|
+
/** ISO country codes */
|
|
26
|
+
countries?: string[];
|
|
27
|
+
/** User agents */
|
|
28
|
+
userAgents?: string[];
|
|
29
|
+
/** Preferred languages */
|
|
30
|
+
languages?: string[];
|
|
31
|
+
/**
|
|
32
|
+
* Number of hits
|
|
33
|
+
* @automated
|
|
34
|
+
*/
|
|
35
|
+
hits?: number;
|
|
36
|
+
/**
|
|
37
|
+
* Log reference
|
|
38
|
+
* @automated
|
|
39
|
+
*/
|
|
40
|
+
lastLogRef?: DocumentReference<LogData>;
|
|
41
|
+
}
|
|
@@ -49,7 +49,7 @@ export declare function onUpdated<T extends SharedData>(collectionPath: string,
|
|
|
49
49
|
* @param callback callback fn
|
|
50
50
|
* @returns firebase function
|
|
51
51
|
*/
|
|
52
|
-
export declare function
|
|
52
|
+
export declare function onDeleted<T extends SharedData>(collectionPath: string, callback: (deletedDoc: QueryDocumentSnapshot<T>, utils: {
|
|
53
53
|
deletedAt: Date;
|
|
54
54
|
logger: tLogger;
|
|
55
55
|
}) => void): import("firebase-functions/core").CloudFunction<import("firebase-functions/v2/firestore").FirestoreEvent<import("firebase-functions/v2/firestore").QueryDocumentSnapshot | undefined, Record<string, string>>>;
|
|
@@ -51,8 +51,14 @@ export function onUpdated(collectionPath, callback, { defaults = {} } = {}) {
|
|
|
51
51
|
const newDoc = data?.after;
|
|
52
52
|
const oldDoc = data?.before;
|
|
53
53
|
if (!newDoc || !oldDoc) return null;
|
|
54
|
-
const {
|
|
55
|
-
|
|
54
|
+
const {
|
|
55
|
+
updatedAt: oldUpdatedAt,
|
|
56
|
+
createdAt: newCreatedAt,
|
|
57
|
+
updatedByRef,
|
|
58
|
+
deletedByRef,
|
|
59
|
+
lock
|
|
60
|
+
} = newDoc.data();
|
|
61
|
+
const { updatedAt: newUpdatedAt, createdAt: oldCreatedAt = newCreatedAt } = oldDoc.data();
|
|
56
62
|
const at = updatedByRef?.parent.parent || firebaseFirestore;
|
|
57
63
|
const logger = makeFunctionsLogger(at, updatedByRef, metadata);
|
|
58
64
|
if (deletedByRef && (!lock || Array.isArray(lock) && !lock.length)) {
|
|
@@ -60,10 +66,13 @@ export function onUpdated(collectionPath, callback, { defaults = {} } = {}) {
|
|
|
60
66
|
}
|
|
61
67
|
if (!oldUpdatedAt || !newUpdatedAt || !newUpdatedAt.isEqual(oldUpdatedAt)) return null;
|
|
62
68
|
const callbackData = await callback?.(newDoc, oldDoc, { updatedAt, logger });
|
|
63
|
-
return newDoc.ref.set(
|
|
69
|
+
return newDoc.ref.set(
|
|
70
|
+
{ ...defaults, ...callbackData, updatedAt, createdAt: oldCreatedAt },
|
|
71
|
+
{ merge: true }
|
|
72
|
+
);
|
|
64
73
|
});
|
|
65
74
|
}
|
|
66
|
-
export function
|
|
75
|
+
export function onDeleted(collectionPath, callback) {
|
|
67
76
|
const document = getDocumentPath(collectionPath);
|
|
68
77
|
return onDocumentDeleted({ document, region: "us-east1" }, async ({ data, ...metadata }) => {
|
|
69
78
|
const { firebaseFirestore } = getFirebase(`onDeleted: "${document}"`);
|
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
import { DocumentReference, type Firestore } from "firebase-admin/firestore";
|
|
2
2
|
import type { tLogger } from "@open-xamu-co/ui-common-types";
|
|
3
3
|
export declare function makeFunctionsLogger(at: DocumentReference | Firestore, authorRef?: DocumentReference, metadata?: Record<string, any>): tLogger;
|
|
4
|
+
/**
|
|
5
|
+
* Log offending requests sources
|
|
6
|
+
*/
|
|
7
|
+
export declare function offenderLogger(at: DocumentReference | Firestore, lastLogRef: DocumentReference, metadata?: any): void;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
DocumentReference,
|
|
3
|
+
FieldValue
|
|
4
|
+
} from "firebase-admin/firestore";
|
|
5
|
+
import acceptLanguageParser from "accept-language-parser";
|
|
2
6
|
import { getLog } from "./logs.js";
|
|
3
7
|
export function makeFunctionsLogger(at, authorRef, metadata = {}) {
|
|
4
8
|
return function(...args) {
|
|
@@ -15,3 +19,22 @@ export function makeFunctionsLogger(at, authorRef, metadata = {}) {
|
|
|
15
19
|
}
|
|
16
20
|
};
|
|
17
21
|
}
|
|
22
|
+
export function offenderLogger(at, lastLogRef, metadata) {
|
|
23
|
+
if (!metadata || typeof metadata !== "object") return;
|
|
24
|
+
const headers = metadata.headers || {};
|
|
25
|
+
const ip = headers["cf-connecting-ip"] || headers["x-fah-client-ip"] || headers["ip"];
|
|
26
|
+
const userAgent = headers["from"] || headers["user-agent"];
|
|
27
|
+
const country = headers["cf-ipcountry"];
|
|
28
|
+
const [preferredLanguage] = acceptLanguageParser.parse(headers["accept-language"]);
|
|
29
|
+
if (!ip) return;
|
|
30
|
+
const offendersRef = at.collection("offenders");
|
|
31
|
+
const offenderDoc = offendersRef.doc(ip);
|
|
32
|
+
const offenderData = { ip, hits: FieldValue.increment(1), lastLogRef };
|
|
33
|
+
if (country) offenderData.countries = FieldValue.arrayUnion(country);
|
|
34
|
+
if (userAgent) offenderData.userAgents = FieldValue.arrayUnion(userAgent);
|
|
35
|
+
if (preferredLanguage) {
|
|
36
|
+
const { code, region } = preferredLanguage;
|
|
37
|
+
offenderData.languages = FieldValue.arrayUnion(`${code}-${region}`);
|
|
38
|
+
}
|
|
39
|
+
offenderDoc.set(offenderData, { merge: true });
|
|
40
|
+
}
|
|
@@ -11,5 +11,25 @@ export declare function getWords(phrase: string): string[];
|
|
|
11
11
|
export declare function soundexEs(phrase: string): string;
|
|
12
12
|
/**
|
|
13
13
|
* Generate indexes to be used as tokens in a fuzzy search
|
|
14
|
+
*
|
|
15
|
+
* Indexes allow to search for a phrase in a fuzzy way
|
|
16
|
+
*
|
|
17
|
+
* @param phrase phrase to generate indexes for
|
|
18
|
+
* @param soundexAlgorithm soundex algorithm to use
|
|
19
|
+
* @returns array of indexes
|
|
20
|
+
*/
|
|
21
|
+
export declare function getSearchIndexes(phrase: string, soundexAlgorithm?: (phrase: string) => string): string[];
|
|
22
|
+
/**
|
|
23
|
+
* Generate indexes to be used as tokens in a fuzzy search
|
|
24
|
+
*
|
|
25
|
+
* Indexes allow to search for a phrase in a fuzzy way
|
|
26
|
+
* Weights allow to sort results based on their relevance
|
|
27
|
+
*
|
|
28
|
+
* @param phrase phrase to generate indexes for
|
|
29
|
+
* @param soundexAlgorithm soundex algorithm to use
|
|
30
|
+
* @returns array of objects with index and weight
|
|
14
31
|
*/
|
|
15
|
-
export declare function
|
|
32
|
+
export declare function getWeightedSearchIndexes(phrase: string, soundexAlgorithm?: (phrase: string) => string): {
|
|
33
|
+
indexes: string[];
|
|
34
|
+
indexesWeights: string[];
|
|
35
|
+
};
|