strapi-plugin-firebase-authentication 1.0.8 → 1.0.13

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 CHANGED
@@ -1,63 +1,297 @@
1
- <img src="/Gen Types Logo.png" style="height: 70px; margin: 0px; border-radius: 12px;" />
1
+ # Strapi Plugin Firebase Authentication
2
2
 
3
- # Strapi Plugin Gen Types
3
+ Welcome to the Strapi plugin for Firebase Authentication! This plugin seamlessly integrates Firebase Authentication with
4
+ your Strapi Headless CMS, allowing you to manage and authenticate Firebase users directly from the Strapi moderation
5
+ panel. This guide will take you through the installation and configuration process and provide information on how to use
6
+ this plugin with iOS and Android apps. This plugin would be enabled by default for super admins only.
4
7
 
5
- Generate types for the different collections, single types & components found in your application.
8
+ ## How it works
6
9
 
7
- ![Screenshot of Gen Types UI in Strapi Admin Panel](/screenshot.jpeg)
10
+ The Firebase Auth plugin works by authenticating users using Firebase Authentication. Once a user is authenticated, the
11
+ plugin creates a Strapi user account for them if it doesn't already exist. The plugin also syncs the user's Firebase
12
+ data with their Strapi account.
8
13
 
9
- > This plugin is still in development. Please use with caution.
14
+ ## Table of Contents
10
15
 
11
- > This plugin will not run in production. It is only meant to be used in development.
16
+ 1. [Installation](#installation)
17
+ 2. [Configuration](#configuration)
18
+ 3. [Usage](#usage)
19
+ 4. [Client Setup](#client-setup)
20
+ 5. [Question and issues](#questions-and-issues)
12
21
 
13
22
  ## Installation
14
23
 
24
+ To get started, you need to install the Firebase Auth plugin for Strapi. We recommend using yarn for this installation.
25
+
26
+ ### Via Command Line
27
+
28
+ ```bash
29
+ yarn add @meta-cto/strapi-plugin-firebase-auth
30
+ ```
31
+
32
+ Once the installation is complete, you must rebuild your Strapi instance. You can do this with the following commands:
33
+
15
34
  ```bash
16
- yarn add strapi-plugin-firebase-authentication
35
+ yarn build
36
+ yarn develop
17
37
  ```
18
38
 
39
+ Alternatively, you can run Strapi in development mode with the `--watch-admin` option:
40
+
19
41
  ```bash
20
- npm install strapi-plugin-firebase-authentication
42
+ yarn develop --watch-admin
21
43
  ```
22
44
 
45
+ The **Firebase Auth** plugin should now be available in the **Plugins** section of your Strapi sidebar.
46
+
23
47
  ## Configuration
24
48
 
25
- You can configure the plugin by updating the `config/plugins.ts` file in your Strapi project.
49
+ In order to configure the Firebase Auth plugin, follow these steps:
50
+
51
+ ### Step 1 - Enable the Plugin
52
+
53
+ In your Strapi project, edit the `config/plugins.js` or `config/<env>/plugins.js` file to enable the Firebase Auth
54
+ plugin. If the file doesn't exist, create it manually. If you already have configurations for other plugins, add
55
+ the `firebase-auth` section to your existing `plugins` configuration.
26
56
 
27
- The following options are available:
57
+ To ensure the security of sensitive information, we have implemented a robust encryption process for the Firebase config JSON file in this project. The encrypted data is then stored as a hash in the database. Follow the steps below to set up and integrate Firebase with Strapi securely.
28
58
 
29
- - `singleFile` - Whether to generate a single file for all types or separate files for each collection. Default: `false`
59
+ ```js
60
+ module.exports = () => ({
61
+ // ...
30
62
 
31
- ```typescript
32
- // config/plugins.ts
33
- export default ({ env }) => ({
34
- "firebase-authentication": {
63
+ "firebase-auth": {
35
64
  enabled: true,
36
- config: {
37
- FIREBASE_JSON_ENCRYPTION_KEY: env("FIREBASE_JSON_ENCRYPTION_KEY", "your-default-key"),
38
- },
65
+ config: { FIREBASE_JSON_ENCRYPTION_KEY: "encryptMe" },
39
66
  },
67
+
68
+ // ...
40
69
  });
41
70
  ```
42
71
 
43
- The plugin will generate types for the collections found in the `api` folder of your Strapi project.
72
+ Replace `"encryptMe"` with a strong and secure key. This key will be used in the encryption and decryption process.
73
+
74
+ ### Step 2: Firebase Configuration Encryption and Integration with Strapi
75
+
76
+ To ensure the security of sensitive information, we have implemented a robust encryption process for the Firebase config JSON file in this project. The encrypted data is then stored as a hash in the database. Follow the steps below to set up and integrate Firebase with Strapi securely.
77
+
78
+ #### Step 1: Obtain Firebase Service Account Key
79
+
80
+ Navigate to the [Firebase Console](https://console.firebase.google.com/) and access your project. In the settings, locate the service account section and download the JSON key file. This file contains sensitive information required for Firebase Authentication.
81
+
82
+ #### Step 2: Submit Service Account Key in Strapi Settings
83
+
84
+ Access the Strapi admin panel and navigate to the settings page. Look for the section related to Firebase integration. Here, you will find an option to submit the `.json` service account key file. Upload the file you obtained in Step 2.
85
+
86
+ This service account key is essential for proper authentication with Firebase. It contains the necessary credentials for your Firebase project.
87
+
88
+ #### Step 3: Save Changes
89
+
90
+ After submitting the service account key, make sure to save the changes in the Strapi settings. This ensures that the encrypted configuration is stored securely in the database.
91
+ the `.json` [service account key file](https://firebase.google.com/docs/app-distribution/authenticate-service-account).
92
+ This key is essential for Firebase Authentication to work properly.
93
+
94
+ ### Step 4 - Rebuild Admin Panel
95
+
96
+ After configuring the plugin, rebuild the Strapi admin panel:
97
+
98
+ ```bash
99
+ npm run build
100
+ ```
101
+
102
+ Alternatively, you can simply delete the existing `./build` directory.
103
+
104
+ ### Step 5 - Grant Public Permissions
105
+
106
+ From the Strapi admin panel, navigate to "Users-permissions" and grant public role
107
+ to `{Your domain or localhost}/admin/settings/users-permissions/roles/2`. Make sure to enable public access to the
108
+ Firebase Authentication endpoint.
109
+
110
+ That's it! You're ready to use Firebase Authentication in your Strapi project. Enjoy! 🎉
111
+
112
+ ## Usage
113
+
114
+ ### Handling User Information
115
+
116
+ To ensure proper handling of user information, make sure to include the following fields in the user object:
117
+
118
+ - `firebaseUserID` is the field that maps firebase user object to strapi user object.
119
+
120
+ These fields can be populated during the creation of the user object if `profileMetaData` is provided.
121
+
122
+ - `firstName`
123
+ - `lastName`
124
+ - `phoneNumber`
125
+ - `email`
126
+
127
+ #### Using `firebase-auth` Endpoint
128
+
129
+ When interacting with the `firebase-auth` endpoint, use the following JSON structure in the request body:
130
+
131
+ ```json
132
+ {
133
+ "idToken": "{{idToken}}",
134
+ "profileMetaData": {
135
+ "firstName": "name",
136
+ "lastName": "name",
137
+ "email": "email@gmail.com",
138
+ "phoneNumber": "+100000000"
139
+ }
140
+ }
141
+ ```
142
+
143
+ These values will be utilized only when the user does not exist and will be ignored in other cases.
144
+
145
+ #### Hint for strapiKMM SDK Users
146
+
147
+ If you are using our `strapiKMM SDK`, which is fully compatible with the plugin, user information will be populated automatically when signing in with Google or Apple. You don't need to manually handle these fields when using the SDK.
148
+
149
+ These values will be applied only when the user is being created for the first time. If the user already exists, the provided data will be ignored, and the existing user information will be retained.
150
+
151
+ ### Client Links and Token Retrieval
152
+
153
+ To enable Firebase Authentication in your iOS, Android, or web app and obtain authentication tokens, follow the provided
154
+ links and their brief descriptions:
155
+
156
+ - **Android Firebase Setup:**
157
+ [Link](https://firebase.google.com/docs/android/setup)
158
+
159
+ _Set up Firebase Authentication in your Android app by following the instructions on this page. It will guide you
160
+ through integrating Firebase into your Android project._
161
+
162
+ - **iOS Firebase Setup:**
163
+ [Link](https://firebase.google.com/docs/ios/setup)
164
+
165
+ _For iOS app integration, this link will lead you to Firebase's official documentation. It outlines the steps to add
166
+ Firebase Authentication to your iOS project._
167
+
168
+ - **Web Firebase Setup:**
169
+ [Link](https://firebase.google.com/docs/web/setup)
170
+
171
+ _If you're looking to incorporate Firebase Authentication into your web application, this link provides comprehensive
172
+ guidance on setting up Firebase in a web project. It's an essential resource for web-based authentication using
173
+ Firebase._
174
+
175
+ ## Client setup
176
+
177
+ **Android Sample:**
178
+
179
+ - To set up Google Sign-In on Android, follow the official Firebase
180
+ documentation: [Android Firebase Authentication with Google](https://firebase.google.com/docs/auth/android/google-signin)
181
+ - After signing with Google,you need to get the GoogleAuthProvider Credential and pass it to firebaseSDK to be able to get the user token
182
+ - Sample Code:
183
+
184
+ ```kotlin
185
+ // Obtain an ID token from Google. Use it to authenticate with Firebase.
186
+ val firebaseCredential = GoogleAuthProvider.getCredential(idToken, null)
187
+ auth.signInWithCredential(firebaseCredential)
188
+ .addOnCompleteListener(this) { task ->
189
+ if (task.isSuccessful) {
190
+ val token = it.result?.token
191
+ // Now, you can pass the token to the Firebase plugin by exchanging the Firebase Token using the `/firebase-auth` endpoint.
192
+ } else {
193
+ // If the sign-in fails, display a message to the user.
194
+ Log.w(TAG, "signInWithCredential:failure", task.exception)
195
+ }
196
+ }
197
+ ```
44
198
 
45
- It will also add a few extra interfaces like `User`, `Role`, `Media` etc.
199
+ **iOS Sample:**
200
+
201
+ - For iOS, use the Firebase Authentication with Google Sign-In
202
+ guide: [iOS Firebase Authentication with Google](https://firebase.google.com/docs/auth/ios/google-signin)
203
+ - After signing with Google,you need to get the GoogleAuthProvider Credential and pass it to firebaseSDK to be able to get the user token
204
+
205
+ - Sample Code:
206
+
207
+ ```swift
208
+ guard let clientID = FirebaseApp.app()?.options.clientID else { return }
209
+
210
+ // Create Google Sign In configuration object.
211
+ let config = GIDConfiguration(clientID: clientID)
212
+ GIDSignIn.sharedInstance.configuration = config
213
+
214
+ // Start the sign in flow!
215
+ GIDSignIn.sharedInstance.signIn(withPresenting: self) { [unowned self] result, error in
216
+ guard error == nil else {
217
+ // ...
218
+ }
219
+
220
+ guard let user = result?.user,
221
+ let idToken = user.idToken?.tokenString
222
+ else {
223
+ // ...
224
+ }
225
+
226
+ let credential = GoogleAuthProvider.credential(withIDToken: idToken,
227
+ accessToken: user.accessToken.tokenString)
228
+
229
+ // ...
230
+
231
+ Auth.auth().signIn(with: credential) { result, error in
232
+
233
+ // At this point, our user is signed in
234
+ // Now you need to pass the token to firebasePlugin using exchange the firebase Token using `/firebase-auth` endpoint
235
+ }
236
+
237
+
238
+ }
239
+ ```
240
+
241
+ **Web Sample:**
242
+
243
+ - To set up Firebase Authentication with Google Sign-In on the web, follow this Firebase
244
+ documentation: [Web Firebase Authentication with Google](https://firebase.google.com/docs/auth/web/google-signin)
245
+ - After signing with Google,you need to get the GoogleAuthProvider Credential and pass it to firebaseSDK to be able to get the user token
246
+ - Sample Code:
247
+
248
+ ```javascript
249
+ import { getAuth, signInWithPopup, GoogleAuthProvider } from "firebase/auth";
250
+
251
+ const auth = getAuth();
252
+ signInWithPopup(auth, provider)
253
+ .then((result) => {
254
+ // This gives you a Google Access Token. You can use it to access the Google API.
255
+ const credential = GoogleAuthProvider.credentialFromResult(result);
256
+ const token = credential.accessToken;
257
+ // The signed-in user info.
258
+ const user = result.user;
259
+ // IdP data available using getAdditionalUserInfo(result)
260
+ // ...
261
+ })
262
+ .catch((error) => {
263
+ // Handle Errors here.
264
+ const errorCode = error.code;
265
+ const errorMessage = error.message;
266
+ // The email of the user's account used.
267
+ const email = error.customData.email;
268
+ // The AuthCredential type that was used.
269
+ const credential = GoogleAuthProvider.credentialFromError(error);
270
+ // ...
271
+ });
272
+ ```
46
273
 
47
- ## Admin UI
274
+ These samples will guide you on how to implement Google Sign-In and obtain the authentication token, which you can then
275
+ pass to the Firebase plugin for user authentication using `/firebase-auth` endpoint
48
276
 
49
- The plugin will add a new menu item `Generated Types`. This page will show the generated interfaces.
277
+ **For More Samples:**
50
278
 
51
- You can expand each interface to see the fields and their types.
279
+ If you need additional samples for authentication methods like Sign-In with Apple, Email and Password, or others, please refer to the official Firebase documentation for comprehensive details:
52
280
 
53
- Clicking on the copy button will copy the interface to your clipboard.
281
+ - [Firebase Official Documentation](https://firebase.google.com/docs/)
54
282
 
55
- ## License
283
+ **Short Links to Specific Authentication Methods:**
56
284
 
57
- MIT
285
+ - **Sign-In with Apple:**
286
+ To ensure a smooth user login experience with Apple authentication, it’s essential to include the appleEmail field in the user object within the Strapi dashboard.
58
287
 
59
- ## Contributing
288
+ - Android: [Link](https://firebase.google.com/docs/auth/android/apple)
289
+ - iOS: [Link](https://firebase.google.com/docs/auth/ios/apple)
290
+ - Web: [Link](https://firebase.google.com/docs/auth/web/apple)
60
291
 
61
- I am super new to React. I prefer Nuxt. I am not sure if how I implemented the Admin UI is the best way to do it. I would appreciate any help in improving it. Thanks.
292
+ - **Email and Password Authentication:**
293
+ - Android: [Link](https://firebase.google.com/docs/auth/android/password-auth)
294
+ - iOS: [Link](https://firebase.google.com/docs/auth/ios/password-auth)
295
+ - Web: [Link](https://firebase.google.com/docs/auth/web/password-auth)
62
296
 
63
- Just fork the repo and create a PR. I will be happy to merge it.
297
+ These short links will take you directly to Firebase's official documentation pages for each authentication method, where you can find in-depth information and code samples.
@@ -5,14 +5,14 @@ const admin = require("@strapi/strapi/admin");
5
5
  const reactRouterDom = require("react-router-dom");
6
6
  const react = require("react");
7
7
  const designSystem = require("@strapi/design-system");
8
- const index = require("./index-BzkEABvl.js");
8
+ const index = require("./index-DMBPEFUy.js");
9
9
  const reactIntl = require("react-intl");
10
10
  const icons = require("@strapi/icons");
11
11
  const rx = require("react-icons/rx");
12
12
  const styled = require("styled-components");
13
13
  const ai = require("react-icons/ai");
14
14
  const md = require("react-icons/md");
15
- const api = require("./api-vCRJO8qn.js");
15
+ const api = require("./api-DPtT1Bpu.js");
16
16
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
17
17
  const styled__default = /* @__PURE__ */ _interopDefault(styled);
18
18
  const fetchUsers = async (query = {}) => {
@@ -2607,14 +2607,7 @@ var implementation$1 = function bind(that) {
2607
2607
  };
2608
2608
  var implementation = implementation$1;
2609
2609
  var functionBind = Function.prototype.bind || implementation;
2610
- var functionCall;
2611
- var hasRequiredFunctionCall;
2612
- function requireFunctionCall() {
2613
- if (hasRequiredFunctionCall) return functionCall;
2614
- hasRequiredFunctionCall = 1;
2615
- functionCall = Function.prototype.call;
2616
- return functionCall;
2617
- }
2610
+ var functionCall = Function.prototype.call;
2618
2611
  var functionApply;
2619
2612
  var hasRequiredFunctionApply;
2620
2613
  function requireFunctionApply() {
@@ -2626,12 +2619,12 @@ function requireFunctionApply() {
2626
2619
  var reflectApply = typeof Reflect !== "undefined" && Reflect && Reflect.apply;
2627
2620
  var bind$2 = functionBind;
2628
2621
  var $apply$1 = requireFunctionApply();
2629
- var $call$2 = requireFunctionCall();
2622
+ var $call$2 = functionCall;
2630
2623
  var $reflectApply = reflectApply;
2631
2624
  var actualApply = $reflectApply || bind$2.call($call$2, $apply$1);
2632
2625
  var bind$1 = functionBind;
2633
2626
  var $TypeError$4 = type;
2634
- var $call$1 = requireFunctionCall();
2627
+ var $call$1 = functionCall;
2635
2628
  var $actualApply = actualApply;
2636
2629
  var callBindApplyHelpers = function callBindBasic(args) {
2637
2630
  if (args.length < 1 || typeof args[0] !== "function") {
@@ -2746,7 +2739,7 @@ var getProto = requireGetProto();
2746
2739
  var $ObjectGPO = requireObject_getPrototypeOf();
2747
2740
  var $ReflectGPO = requireReflect_getPrototypeOf();
2748
2741
  var $apply = requireFunctionApply();
2749
- var $call = requireFunctionCall();
2742
+ var $call = functionCall;
2750
2743
  var needsEval = {};
2751
2744
  var TypedArray = typeof Uint8Array === "undefined" || !getProto ? undefined$1 : getProto(Uint8Array);
2752
2745
  var INTRINSICS = {
@@ -3,14 +3,14 @@ import { getFetchClient, Pagination, useQueryParams as useQueryParams$1, useNoti
3
3
  import { useNavigate, useLocation, Routes, Route } from "react-router-dom";
4
4
  import { useState, useEffect, useMemo, useCallback, useRef, useLayoutEffect, memo } from "react";
5
5
  import { Flex, Tooltip, Thead, Tr, Th, Tbody, Td, Checkbox, Box, Button, Typography, Dialog, Table, SearchForm, Searchbar, TextInput, Main, Link } from "@strapi/design-system";
6
- import { P as PLUGIN_ID } from "./index-8ErokDMe.mjs";
6
+ import { P as PLUGIN_ID } from "./index-CALp4X47.mjs";
7
7
  import { useIntl } from "react-intl";
8
8
  import { Key, Trash, WarningCircle, ArrowLeft, Plus } from "@strapi/icons";
9
9
  import { RxCheck, RxCross2 } from "react-icons/rx";
10
10
  import styled from "styled-components";
11
11
  import { AiOutlineUserAdd, AiFillPhone, AiFillMail, AiFillYahoo, AiFillGithub, AiFillTwitterCircle, AiFillFacebook, AiFillApple, AiFillGoogleCircle } from "react-icons/ai";
12
12
  import { MdPassword } from "react-icons/md";
13
- import { g as getFirebaseConfig } from "./api-CSB13cU_.mjs";
13
+ import { g as getFirebaseConfig } from "./api-4hcml0jk.mjs";
14
14
  const fetchUsers = async (query = {}) => {
15
15
  if (!query.page) {
16
16
  query.page = 1;
@@ -1,5 +1,5 @@
1
1
  import { getFetchClient } from "@strapi/strapi/admin";
2
- import { P as PLUGIN_ID } from "./index-8ErokDMe.mjs";
2
+ import { P as PLUGIN_ID } from "./index-CALp4X47.mjs";
3
3
  const saveFirebaseConfig = async (json) => {
4
4
  const url = `/${PLUGIN_ID}/settings/firebase-config`;
5
5
  const { post } = getFetchClient();
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  const admin = require("@strapi/strapi/admin");
3
- const index = require("./index-BzkEABvl.js");
3
+ const index = require("./index-DMBPEFUy.js");
4
4
  const saveFirebaseConfig = async (json) => {
5
5
  const url = `/${index.PLUGIN_ID}/settings/firebase-config`;
6
6
  const { post } = admin.getFetchClient();
@@ -1,7 +1,7 @@
1
1
  const en = {
2
- "app.name": "Gen Types",
3
- "page.title": "Generated Types",
4
- "page.subTitle": "Quickly view & copy the types generated for your Strapi collections",
2
+ "app.name": "Firebase Authentication",
3
+ "page.title": "Firebase Authentication",
4
+ "page.subTitle": "Integrate Firebase Authentication with Strapi",
5
5
  "page.copy.notSupported.title": "Copy not supported",
6
6
  "page.copy.notSupported.message": "Your browser does not support copying to clipboard",
7
7
  "page.copy.success.title": "Copied to Clipboard",
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const en = {
4
- "app.name": "Gen Types",
5
- "page.title": "Generated Types",
6
- "page.subTitle": "Quickly view & copy the types generated for your Strapi collections",
4
+ "app.name": "Firebase Authentication",
5
+ "page.title": "Firebase Authentication",
6
+ "page.subTitle": "Integrate Firebase Authentication with Strapi",
7
7
  "page.copy.notSupported.title": "Copy not supported",
8
8
  "page.copy.notSupported.message": "Your browser does not support copying to clipboard",
9
9
  "page.copy.success.title": "Copied to Clipboard",
@@ -49,7 +49,7 @@ const index = {
49
49
  id: `${PLUGIN_ID}.page.title`,
50
50
  defaultMessage: PLUGIN_ID
51
51
  },
52
- Component: () => import("./App-DaxdXe5h.mjs").then((mod) => ({
52
+ Component: () => import("./App-B3HcVa5j.mjs").then((mod) => ({
53
53
  default: mod.App
54
54
  })),
55
55
  permissions: PERMISSIONS["menu-link"]
@@ -71,7 +71,7 @@ const index = {
71
71
  id: "settings",
72
72
  to: `/settings/${PLUGIN_ID}`,
73
73
  async Component() {
74
- const component = await import("./index-DIqCTZth.mjs");
74
+ const component = await import("./index-CrGRt-Ya.mjs");
75
75
  return component.default;
76
76
  },
77
77
  permissions: PERMISSIONS["menu-link"]
@@ -88,7 +88,7 @@ const index = {
88
88
  async registerTrads({ locales }) {
89
89
  const importedTrads = await Promise.all(
90
90
  locales.map((locale) => {
91
- return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("./en-BRmJb_fY.mjs") }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
91
+ return __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("./en-D32b9qK-.mjs") }), `./translations/${locale}.json`, 3).then(({ default: data }) => {
92
92
  return {
93
93
  data: prefixPluginTranslations(data, PLUGIN_ID),
94
94
  locale