memi-board 0.52.0 → 0.52.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.
- package/README.md +297 -297
- package/dist/{commentImages-CzXO42gE.js → commentImages-D_JJnuoj.js} +5 -4
- package/dist/commentImages-D_JJnuoj.js.map +1 -0
- package/dist/composables/useMemiBoardAutoTranslate.d.ts +1 -0
- package/dist/composables/useMemiBoardComments.d.ts +35 -2
- package/dist/composables/useMemiBoardWritingAssistant.d.ts +6 -1
- package/dist/{en-CmPLbFcN.js → en-DSCLJyUd.js} +4 -3
- package/dist/en-DSCLJyUd.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +987 -903
- package/dist/index.js.map +1 -1
- package/dist/runtime/components/CommentAi.vue +93 -0
- package/dist/runtime/components/CommentFeed.vue +3 -3
- package/dist/runtime/components/CommentForm.vue +11 -4
- package/dist/runtime/components/CommentItem.vue +20 -8
- package/dist/runtime/components/Editor.vue +0 -2
- package/dist/runtime/components/MiniComments.vue +3 -3
- package/dist/runtime/components/UserCommentList.vue +3 -3
- package/dist/storage.js +1 -1
- package/dist/types.d.ts +10 -1
- package/dist/utils/localizedFields.d.ts +3 -1
- package/docs/firebase-setup.md +85 -85
- package/docs/firestore.rules.example +58 -58
- package/docs/host-integration.md +80 -80
- package/docs/internationalization.md +76 -72
- package/docs/roles-migration.md +18 -18
- package/docs/storage.rules.example +18 -18
- package/package.json +2 -2
- package/dist/commentImages-CzXO42gE.js.map +0 -1
- package/dist/en-CmPLbFcN.js.map +0 -1
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Internationalization and content translation
|
|
2
2
|
|
|
3
|
-
[
|
|
3
|
+
[Installation guide](host-integration.md) · [README](../README.md) · [Firebase setup](firebase-setup.md)
|
|
4
4
|
|
|
5
|
-
`i18n.enabled
|
|
5
|
+
`i18n.enabled` and `translation.enabled` are supported in **memi-board 0.47.0 or later**. Existing host apps should update with `pnpm add memi-board@^0.47.0` and commit the lockfile as well.
|
|
6
6
|
|
|
7
|
-
## 1.
|
|
7
|
+
## 1. Choose a mode for your service
|
|
8
8
|
|
|
9
|
-
**UI
|
|
9
|
+
**UI language** is the language of on-screen text such as save, cancel, help messages, and dates. **Content translation** generates and displays board names and descriptions, section titles, and post titles, summaries, and bodies in other languages.
|
|
10
10
|
|
|
11
|
-
|
|
|
11
|
+
| Purpose | `i18n.enabled` | `translation.enabled` | Behavior |
|
|
12
12
|
|---|---|---|---|
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
|
|
|
13
|
+
| Site that uses only Korean or only English | `false` | Not needed | UI fixed by `locale`, content shown in the original, translation features hidden |
|
|
14
|
+
| Site that needs only a multilingual UI | `true` | `false` | UI language switching, content shown in the original, translation features hidden |
|
|
15
|
+
| Site that needs a multilingual UI and content translation | `true` | `true` | Both UI language switching and content translation |
|
|
16
|
+
| Keep existing behavior | Omitted | Omitted | Both options default to `true` |
|
|
17
17
|
|
|
18
|
-
`i18n.enabled: false
|
|
18
|
+
`i18n.enabled: false` takes precedence. In that case, content translation does not run even if `translation.enabled: true` is set. Turning off either feature does not delete existing translation data.
|
|
19
19
|
|
|
20
|
-
## 2.
|
|
20
|
+
## 2. Ready-to-copy configurations
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
Put the `memiBoard` block below inside the host's `defineNuxtConfig({ ... })`. For the rest, such as Firebase initialization, follow the [installation guide](host-integration.md).
|
|
23
23
|
|
|
24
|
-
###
|
|
24
|
+
### Single language only
|
|
25
25
|
|
|
26
26
|
```ts
|
|
27
27
|
memiBoard: {
|
|
28
|
-
locale: 'ko', //
|
|
28
|
+
locale: 'ko', // 'en' for English-only
|
|
29
29
|
i18n: { enabled: false }
|
|
30
30
|
}
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
- `@nuxtjs/i18n
|
|
33
|
+
- Uses `locale`, ignoring the host's current language and per-board languages. If omitted or unsupported, it is `ko`.
|
|
34
|
+
- Hides the board language selector, translate buttons, the auto-translate toggle, and the translate menu in the writing AI.
|
|
35
|
+
- Content is shown in the original even if saved translations exist.
|
|
36
|
+
- Even if a board's auto-translate toggle was previously on, nothing is translated when the settings are saved.
|
|
37
|
+
- `@nuxtjs/i18n` does not need to be installed. Even if the host app already uses it, the board stays fixed to the specified language.
|
|
38
38
|
|
|
39
|
-
### UI
|
|
39
|
+
### Multilingual UI, original content
|
|
40
40
|
|
|
41
41
|
```ts
|
|
42
42
|
memiBoard: {
|
|
@@ -46,9 +46,9 @@ memiBoard: {
|
|
|
46
46
|
}
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
Keeps the board language selector and hides only the translation-related UI. Menus, buttons, and dates follow the current screen language, while board labels, descriptions, section titles, and posts are shown as originally written.
|
|
50
50
|
|
|
51
|
-
### UI
|
|
51
|
+
### Multilingual UI and content translation
|
|
52
52
|
|
|
53
53
|
```ts
|
|
54
54
|
memiBoard: {
|
|
@@ -58,24 +58,24 @@ memiBoard: {
|
|
|
58
58
|
}
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
To generate translations, the host's Firebase project must have an AI Logic connection set up. Simply displaying UI language files does not trigger AI requests.
|
|
62
62
|
|
|
63
|
-
## 3.
|
|
63
|
+
## 3. Connect the host app's language switching
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
Supported languages are `ko`, `en`, `ja`, `de`, `fr`, `es`, `pt`, `zh`, `ar`, and `id`. Values such as `en-US` and `pt_BR` are normalized to supported codes. When `i18n.enabled` is on, the language is resolved in this order:
|
|
66
66
|
|
|
67
|
-
1.
|
|
68
|
-
2.
|
|
69
|
-
3.
|
|
67
|
+
1. The fixed language in the board settings
|
|
68
|
+
2. The language passed from the parent board screen
|
|
69
|
+
3. The current language of the host's `@nuxtjs/i18n`
|
|
70
70
|
4. `memiBoard.locale`
|
|
71
71
|
5. `ko`
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
To follow the site's language switching, set the board's language to **Auto** in the board settings. A language fixed per board takes precedence over the site language.
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
If the host app uses `@nuxtjs/i18n`:
|
|
76
76
|
|
|
77
77
|
```ts
|
|
78
|
-
// nuxt.config.ts —
|
|
78
|
+
// nuxt.config.ts — merge into the existing config
|
|
79
79
|
modules: ['@nuxt/ui', '@nuxtjs/i18n', 'nuxt-vuefire', 'memi-board'],
|
|
80
80
|
i18n: {
|
|
81
81
|
locales: [
|
|
@@ -92,9 +92,9 @@ memiBoard: {
|
|
|
92
92
|
}
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
This example uses only Korean and English UI. Create messages for the host UI in the host's `i18n/locales/ko.json` and `en.json` (`{}` is fine to start). The package ships the board's own translation files, so don't copy them. Add other languages to the host list as needed.
|
|
96
96
|
|
|
97
|
-
Nuxt UI
|
|
97
|
+
The host app wires up Nuxt UI's internal strings and the site's `<html>` language. For example, a Korean/English host can set this in `app/app.vue`:
|
|
98
98
|
|
|
99
99
|
```vue
|
|
100
100
|
<script setup lang="ts">
|
|
@@ -111,52 +111,52 @@ useHead({ htmlAttrs: { lang: () => uiLocale.value.code, dir: () => uiLocale.valu
|
|
|
111
111
|
</template>
|
|
112
112
|
```
|
|
113
113
|
|
|
114
|
-
|
|
114
|
+
Sites that use layouts keep their existing `<NuxtLayout>` structure. If the board is single-language and the host is multilingual, the site-wide `<html>` and `UApp` language are determined by the host's policy.
|
|
115
115
|
|
|
116
|
-
## 4.
|
|
116
|
+
## 4. When translations run and are saved
|
|
117
117
|
|
|
118
|
-
|
|
|
118
|
+
| Target | When it runs | When it is saved |
|
|
119
119
|
|---|---|---|
|
|
120
|
-
|
|
|
121
|
-
|
|
|
122
|
-
|
|
|
123
|
-
|
|
|
124
|
-
|
|
|
125
|
-
|
|
|
120
|
+
| Board label and description: manual | Click **Translate into 10 languages** | Click **Save** in the settings after translating |
|
|
121
|
+
| Board label and description: auto | Turn on the auto-translate toggle and click **Save** | Saved with the settings after translation completes |
|
|
122
|
+
| Home section titles | Saving the section layout | Saved with the layout after translation |
|
|
123
|
+
| Title, summary, and body of an existing post | Click **Translate and save in 10 languages** in the writing AI | Saved to the post immediately after translation completes |
|
|
124
|
+
| New post: auto | Turn on **Automatically translate new posts** in the board settings, then save a new post | Title, summary, and body are translated and saved with the post |
|
|
125
|
+
| New post not yet saved | Click **Translate and save in 10 languages** in the writing AI | Saved together when the new post is saved |
|
|
126
126
|
|
|
127
|
-
10
|
|
127
|
+
The 10 languages include the source language. If the original is Korean, it is translated into the other 9 languages and combined with the Korean original. Typing alone does not send translation requests until you click a translate button or save.
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
If the board name, description, and section titles are the same as when they were translated and all translations exist, retranslation is skipped. The board's auto-translate toggle is off by default. `i18n.enabled` and `translation.enabled` being on by default means the service can use translation; it does not automatically turn on a board's auto-translate toggle.
|
|
130
130
|
|
|
131
|
-
`autoTranslatePosts
|
|
131
|
+
`autoTranslatePosts` applies only to writing new posts and defaults to `false`. Existing boards without the field are treated as off. Posts are not auto-translated on edit. Manually prepared translations are reused if they match the current content. If auto-translation fails, the input is kept, an error is shown, and saving the post is aborted. If translation is turned off service-wide, posts are saved without translation regardless of this option.
|
|
132
132
|
|
|
133
|
-
|
|
133
|
+
Calling `translateBoard()` directly from code translates regardless of the board's current auto-translate toggle. If the service-wide internationalization or translation option is off, it returns the original as-is.
|
|
134
134
|
|
|
135
|
-
## 5. AI
|
|
135
|
+
## 5. AI connection and failure handling
|
|
136
136
|
|
|
137
|
-
[Firebase
|
|
137
|
+
Apply the AI Logic and App Check steps from the [Firebase setup guide](firebase-setup.md) to the host project. The Firebase web app's `projectId`, `appId`, and App Check registration must match. The translation model and App Check token options share the existing `memiBoard.moderation.model` and `moderation.useLimitedUseAppCheckTokens`.
|
|
138
138
|
|
|
139
|
-
`moderation.enabled: false
|
|
139
|
+
`moderation.enabled: false` turns off **moderation**. To also turn off translation, use `translation.enabled: false` or `i18n.enabled: false`. Conversely, turning off translation leaves writing assistants such as spell checking and sentence polishing, and moderation, governed by their own settings.
|
|
140
140
|
|
|
141
|
-
|
|
|
141
|
+
| Situation | Handling |
|
|
142
142
|
|---|---|
|
|
143
|
-
|
|
|
144
|
-
|
|
|
145
|
-
|
|
|
146
|
-
|
|
|
147
|
-
|
|
|
143
|
+
| Manual board translation fails | Input is kept and an error is shown. The user decides whether to save the settings |
|
|
144
|
+
| Automatic board translation fails | Settings and the original are saved, and a translation failure notice is shown |
|
|
145
|
+
| Section translation fails | The original layout is saved, with a console warning |
|
|
146
|
+
| Post translation fails | An error is shown. It does not proceed to saving the translation result |
|
|
147
|
+
| Translation turned off by service option | Auto-translation is skipped and saving proceeds normally. Calling AI translation directly throws a `memi-board/translation-disabled` error |
|
|
148
148
|
|
|
149
|
-
|
|
149
|
+
AI post translation counts as 1 use of the daily writing assistant quota regardless of the number of languages. Calls rejected because translation is disabled are rejected before any AI request or usage update. When enabled, a request that has already started and then fails may still be counted against usage.
|
|
150
150
|
|
|
151
|
-
## 6.
|
|
151
|
+
## 6. Existing data and re-enabling
|
|
152
152
|
|
|
153
|
-
|
|
153
|
+
Translations are stored in the existing documents' `i18n` and `i18nSource`, and post body translations are stored in the corresponding body document. You don't need to migrate data or delete translation fields to turn the feature off.
|
|
154
154
|
|
|
155
|
-
|
|
155
|
+
If the original differs from what it was at translation time, the original is shown instead of that translation. This check stays in place after re-enabling. For example, if you renamed a board while translation was off, the translations of the old name are not shown until you translate again.
|
|
156
156
|
|
|
157
|
-
## 7.
|
|
157
|
+
## 7. UI built by the host app
|
|
158
158
|
|
|
159
|
-
|
|
159
|
+
The package hides only its own UI. Language selectors or translate buttons built by the host app should be controlled in the host using the state below.
|
|
160
160
|
|
|
161
161
|
```vue
|
|
162
162
|
<script setup lang="ts">
|
|
@@ -165,19 +165,23 @@ const { i18nEnabled, translationEnabled } = useMemiBoardI18n()
|
|
|
165
165
|
</script>
|
|
166
166
|
|
|
167
167
|
<template>
|
|
168
|
-
<span v-if="i18nEnabled"
|
|
169
|
-
<span v-if="translationEnabled"
|
|
168
|
+
<span v-if="i18nEnabled">Language switching available</span>
|
|
169
|
+
<span v-if="translationEnabled">Content translation available</span>
|
|
170
170
|
</template>
|
|
171
171
|
```
|
|
172
172
|
|
|
173
|
-
|
|
173
|
+
Outside components, use `isMemiBoardI18nEnabled()` and `isMemiBoardTranslationEnabled()`. Import both explicitly from `memi-board/runtime`. `configureMemiBoard()` accepts the same options, but in a Nuxt host app you only need to set `memiBoard` in `nuxt.config.ts`.
|
|
174
174
|
|
|
175
|
-
## 8.
|
|
175
|
+
## 8. Checklist
|
|
176
176
|
|
|
177
|
-
-
|
|
178
|
-
-
|
|
179
|
-
-
|
|
180
|
-
-
|
|
181
|
-
-
|
|
177
|
+
- Single language: verify that the board's buttons and dates keep the specified language even when the host switches to another language.
|
|
178
|
+
- Content translation off only: verify that the UI changes and that posts with existing translations still show the original.
|
|
179
|
+
- Verify that saving a board with auto-translate on makes no AI requests while translation is disabled.
|
|
180
|
+
- Re-enabling: verify that unchanged originals use the saved translations and changed originals don't use stale translations.
|
|
181
|
+
- Verify that input and settings are preserved when translation fails.
|
|
182
182
|
|
|
183
|
-
|
|
183
|
+
Run the package's regression tests in the development environment with `pnpm test:i18n`.
|
|
184
|
+
|
|
185
|
+
### 게시글 원문 언어 (0.52.1+)
|
|
186
|
+
|
|
187
|
+
게시글 수동·자동 번역은 화면 언어 대신 제목·본문의 실제 언어를 판별해 원문 언어로 저장한다. 영어 화면에서 한국어 글을 번역해도 한국어 원문을 유지하고 영어 번역을 생성한다. 호스트에서 `translatePost({ source })`를 명시하면 그 값을 사용한다. 언어 판별은 번역과 같은 일일 사용 1회 안에서 실행된다. 이전 버전에서 화면 언어와 원문 언어가 다른 상태로 번역해 잘못 저장된 글은 재번역해야 한다.
|
package/docs/roles-migration.md
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
# 0.46
|
|
1
|
+
# 0.46 role migration
|
|
2
2
|
|
|
3
|
-
[
|
|
3
|
+
[Host installation guide](host-integration.md) · [Internationalization and translation](internationalization.md) · [Firebase setup](firebase-setup.md)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
For a new install, set the role of the user document created on sign-in to `owner` from a trusted console or server. The admin → owner and staff → manager migration below is needed only for host apps that used the previous 3 roles. It is not a task of repeatedly converting newly created admins to owner.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Roles: user (regular user), staff (content), manager (settings and staff assignment for assigned boards), admin (full management), owner (assigns administrators).
|
|
8
8
|
|
|
9
|
-
`allowedStaffUids
|
|
9
|
+
`allowedStaffUids` lists content staff, and `allowedManagerUids` lists settings managers. If a manager is assigned only to another board's allowedStaffUids, they manage only content on that board. The global role is an eligibility; the actual scope is determined by the board document. Linking the host's organizations, such as stores, to boards and syncing assignments is the host app's responsibility.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
For compatibility, `isAdmin` includes owner and `isStaff` includes manager. Check the exact role with `role`, `isOwner`, and `isManager`. Use `canConfigureBoard(boardId)` for entering the settings screen and `canManageBoard(boardId)` for content management. The minimum roles for writing posts and comments remain user/staff/admin (manager counts as staff level, owner as admin level).
|
|
12
12
|
|
|
13
13
|
```ts
|
|
14
14
|
// nuxt.config.ts
|
|
15
15
|
memiBoard: {
|
|
16
|
-
roleLabels: { user: '
|
|
16
|
+
roleLabels: { user: 'Customer', staff: 'Store staff', manager: 'Store manager', admin: 'Operator', owner: 'Super admin' }
|
|
17
17
|
}
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
If omitted, the default labels for each language are used. Custom labels apply identically to all languages.
|
|
21
21
|
|
|
22
|
-
##
|
|
22
|
+
## Rollout order
|
|
23
23
|
|
|
24
|
-
1.
|
|
25
|
-
2. Firestore
|
|
26
|
-
3.
|
|
27
|
-
4.
|
|
28
|
-
5.
|
|
24
|
+
1. Apply the new package and role-aware code to the host app.
|
|
25
|
+
2. Merge the Firestore and Storage rule examples into the host's existing rules and test them in the emulator.
|
|
26
|
+
3. Deploy the new rules. An App Hosting deployment alone does not update the rules.
|
|
27
|
+
4. With a trusted Admin SDK, move existing admins to owner and existing staff to manager. Move each board's existing staff UIDs to allowedManagerUids. Leave regular users as they are. If there are several existing admins, all of them become owners, so review the count beforehand.
|
|
28
|
+
5. Deploy the new host app and refresh sign-in state.
|
|
29
29
|
|
|
30
|
-
memi-dev
|
|
30
|
+
memi-dev's scripts/migrate-board-roles.mjs runs as a dry run by default and applies changes in a transaction with --apply. Previous roles and assignments are recorded in memiBoardMigrations/roles-v046, which is blocked from client access. If the completion marker exists, rerunning does not re-promote new roles. Assigning or transferring owner must be done only through trusted server operations.
|
|
31
31
|
|
|
32
|
-
##
|
|
32
|
+
## File permissions
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
Because of the Firestore read limit in Storage rules, the default rules let only the author and a global admin/owner modify or delete other users' files. Do not give staff/manager global file permissions. When staff/manager delete other users' posts, file cleanup uses the existing best-effort approach, so remaining files must be cleaned up by the host server. Host apps where assigned staff need to replace other users' images or attachments must implement a server API that verifies the token and the assignment to that board.
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
Managers cannot change visibility, create or delete boards, change their own manager assignment, or change global roles. Assigned staff can only be chosen from accounts that already have staff/manager eligibility.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// memi-board 0.45.1+ Storage Rules (flat schema, ownerUid metadata)
|
|
2
2
|
// memiBoardPosts/{postId}/attachments|images|comment-images/...
|
|
3
|
-
// postId
|
|
4
|
-
//
|
|
5
|
-
// roles/firebaserules.firestoreServiceAgent
|
|
6
|
-
// firestore.exists/get
|
|
7
|
-
//
|
|
3
|
+
// postId is globally unique, so the boardId prefix is no longer needed.
|
|
4
|
+
// In the host app's Firebase project, the Storage service account must be granted
|
|
5
|
+
// the roles/firebaserules.firestoreServiceAgent role.
|
|
6
|
+
// Without firestore.exists/get read access, image/attachment uploads and file deletes fail as unauthorized.
|
|
7
|
+
// Setup and verification: the "Firestore read access for Storage rules" section of docs/firebase-setup.md.
|
|
8
8
|
|
|
9
9
|
rules_version = '2';
|
|
10
10
|
service firebase.storage {
|
|
@@ -41,12 +41,12 @@ service firebase.storage {
|
|
|
41
41
|
&& firestore.get(postPath).data.authorUid == request.auth.uid;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
//
|
|
45
|
-
// 0.38.0
|
|
46
|
-
//
|
|
47
|
-
// match /memiBoardPosts/{postId} { allow list }
|
|
48
|
-
// {allPaths=**}
|
|
49
|
-
// write
|
|
44
|
+
// When a post is deleted, the package runs listAll on images/, attachments/, and comment-images/.
|
|
45
|
+
// 0.38.0 and earlier use listAll on the parent path (memiBoardPosts/{postId}).
|
|
46
|
+
// The request prefix is always memiBoardPosts/{postId}/ (with a trailing slash), so
|
|
47
|
+
// match /memiBoardPosts/{postId} { allow list } alone results in a 403.
|
|
48
|
+
// {allPaths=**} matches zero or more segments and is needed for folder listing and file get/delete.
|
|
49
|
+
// Don't put write here — the size and image/* limits are handled by the more specific matches below.
|
|
50
50
|
// Global admin maintenance lists the collection root to find abandoned uploads.
|
|
51
51
|
match /memiBoardPosts/{allPaths=**} {
|
|
52
52
|
allow list: if isBoardStaff();
|
|
@@ -67,9 +67,9 @@ service firebase.storage {
|
|
|
67
67
|
|
|
68
68
|
match /memiBoardPosts/{postId}/images/{allPaths=**} {
|
|
69
69
|
allow get: if true;
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
//
|
|
70
|
+
// The editor uploads to the Storage path (using a pre-generated postId) before creating the
|
|
71
|
+
// Firestore document. Pasted images arrive as image/png, etc.
|
|
72
|
+
// Existing posts can be modified only by the author/staff. Files not yet saved are protected by ownerUid.
|
|
73
73
|
allow create, update: if canWritePostFile(postId)
|
|
74
74
|
&& request.resource != null
|
|
75
75
|
&& request.resource.size < 5 * 1024 * 1024
|
|
@@ -77,9 +77,9 @@ service firebase.storage {
|
|
|
77
77
|
allow delete: if canDeletePostFile(postId);
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
//
|
|
80
|
+
// Comment images. These are uploaded before the comment document, so Firestore is not read here.
|
|
81
|
+
// Deletion: the uploader (ownerUid), or the post author / a global admin/owner.
|
|
82
|
+
// Post deletion empties this folder via canDeletePostFile while the post document still exists.
|
|
83
83
|
match /memiBoardPosts/{postId}/comment-images/{commentId}/{fileName} {
|
|
84
84
|
allow get: if true;
|
|
85
85
|
allow create: if isSignedIn()
|
|
@@ -92,7 +92,7 @@ service firebase.storage {
|
|
|
92
92
|
);
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
//
|
|
95
|
+
// Profile photo — the path is fixed to the uid, so only the user can write. Reads are public since it is part of the public profile.
|
|
96
96
|
match /memiBoardUsers/{uid}/avatar.jpg {
|
|
97
97
|
allow get: if true;
|
|
98
98
|
allow write: if isSignedIn()
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memi-board",
|
|
3
|
-
"version": "0.52.
|
|
3
|
+
"version": "0.52.2",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "Nuxt 4 + Nuxt UI + VueFire/Firebase
|
|
5
|
+
"description": "Board (forum) module for Nuxt 4 + Nuxt UI + VueFire/Firebase",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "fkkmemi",
|
|
8
8
|
"repository": {
|