Security News
Weekly Downloads Now Available in npm Package Search Results
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
@fireact.dev/saas
Advanced tools
A comprehensive SaaS toolkit for Firebase applications, featuring subscription management, billing integration, and user management components. Built on top of @fireact.dev/core with TailwindCSS styling.
SaaS components and utilities for fireact.dev applications.
This package requires a fireact.dev application set up with @fireact.dev/core. Please follow the setup instructions at: https://www.npmjs.com/package/@fireact.dev/core
Ensure you have completed the following steps from the core setup:
Run firebase init
to include Cloud Functions in your Firebase setup.
Update Firestore rules:
Example Firestore rules:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Allow authenticated users to read and write their own user document
match /users/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
// Subscription document rules
match /subscriptions/{docId} {
// Allow listing subscriptions for authenticated users
allow list: if request.auth != null;
// Allow get (individual document read) only to users in permissions.access array
allow get: if request.auth != null
&& get(/databases/$(database)/documents/subscriptions/$(docId)).data.permissions.access.hasAny([request.auth.uid]);
// Only allow updates to settings fields if user's UID is in permissions.admin array
allow update: if request.auth != null
&& get(/databases/$(database)/documents/subscriptions/$(docId)).data.permissions.admin.hasAny([request.auth.uid])
&& request.resource.data.diff(resource.data).affectedKeys().hasOnly(['settings']);
// Block all other write operations
allow create, delete: if false;
// Invoices subcollection rules
match /invoices/{invoiceId} {
// Allow reading invoices to subscription admins
allow read: if request.auth != null
&& get(/databases/$(database)/documents/subscriptions/$(docId)).data.permissions.admin.hasAny([request.auth.uid]);
// Block direct writes - only allow through cloud functions
allow write: if false;
}
}
// Invites collection rules
match /invites/{inviteId} {
// Allow reading invites to:
// 1. Subscription admins
// 2. Users whose email matches the invite email
allow read: if request.auth != null && (
get(/databases/$(database)/documents/subscriptions/$(resource.data.subscription_id)).data.permissions.admin.hasAny([request.auth.uid])
|| (request.auth.token.email != null && request.auth.token.email.lower() == resource.data.email)
);
// Block direct writes - only allow through cloud functions
allow write: if false;
}
}
}
npm install @fireact.dev/saas
Install the required peer dependencies:
npm install @stripe/stripe-js
Create src/saasConfig.json
with your SaaS configuration:
{
"stripe": {
"public_api_key": "your-stripe-public-key"
},
"plans": [
{
"id": "free",
"titleKey": "plans.free.title",
"popular": false,
"priceIds": ["your-stripe-price-id"],
"currency": "$",
"price": 0,
"frequency": "week",
"descriptionKeys": [
"plans.free.feature1",
"plans.free.feature2",
"plans.free.feature3",
"plans.free.feature4"
],
"free": true,
"legacy": false
}
],
"permissions": {
"access": {
"label": "Access",
"default": true,
"admin": false
},
"editor": {
"label": "Editor",
"default": false,
"admin": false
},
"admin": {
"label": "Administrator",
"default": false,
"admin": true
}
},
"settings": {
"name": {
"type": "string",
"required": true,
"label": "subscription.name",
"placeholder": "subscription.namePlaceholder"
}
},
"pages": {
"billing": "/subscription/:id/billing",
"createPlan": "/create-plan",
"subscription": "/subscription/:id",
"users": "/subscription/:id/users",
"invite": "/subscription/:id/users/invite",
"settings": "/subscription/:id/settings",
"changePlan": "/subscription/:id/billing/change-plan",
"cancelSubscription": "/subscription/:id/billing/cancel",
"managePaymentMethods": "/subscription/:id/billing/payment-methods",
"updateBillingDetails": "/subscription/:id/billing/update-details",
"transferOwnership": "/subscription/:id/billing/transfer-ownership"
}
}
src/
i18n/
locales/
saas/
en.ts
zh.ts
Modify the tailwind.config.js
file to support the @fireact.dev/saas
package.
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./src/**/*.{js,jsx,ts,tsx}",
"./node_modules/@fireact.dev/core/dist/**/*.{js,mjs}",
"./node_modules/@fireact.dev/saas/dist/**/*.{js,mjs}"
],
theme: {
extend: {},
},
plugins: [],
}
Update your src/App.tsx
to include SaaS components:
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import en from './i18n/locales/en';
import zh from './i18n/locales/zh';
import enSaas from './i18n/locales/saas/en';
import zhSaas from './i18n/locales/saas/zh';
import {
AuthProvider,
ConfigProvider,
LoadingProvider,
PublicLayout,
AuthenticatedLayout,
SignIn,
SignUp,
ResetPassword,
Profile,
EditName,
EditEmail,
ChangePassword,
DeleteAccount,
Logo
} from '@fireact.dev/core';
import {
CreatePlan,
Home,
SubscriptionDashboard,
SubscriptionLayout,
SubscriptionDesktopMenu,
SubscriptionMobileMenu,
SubscriptionProvider,
MainDesktopMenu,
MainMobileMenu,
Billing,
SubscriptionSettings,
ProtectedSubscriptionRoute,
UserList,
InviteUser,
ChangePlan,
CancelSubscription,
ManagePaymentMethods,
UpdateBillingDetails,
TransferSubscriptionOwnership
} from '@fireact.dev/saas';
import config from './config.json';
import saasConfig from './saasConfig.json';
// Initialize i18next
i18n
.use(LanguageDetector)
.use(initReactI18next)
.init({
resources: {
en: {
translation: {
...en,
...enSaas
}
},
zh: {
translation: {
...zh,
...zhSaas
}
}
},
fallbackLng: 'en',
interpolation: {
escapeValue: false
}
});
// Combine paths from both config files
const paths = {
...config.pages,
...saasConfig.pages
};
// Combine configs and include combined paths
const combinedConfig = {
...config,
...saasConfig,
pages: paths
};
function App() {
return (
<Router>
<ConfigProvider config={combinedConfig}>
<AuthProvider>
<LoadingProvider>
<Routes>
<Route element={
<AuthenticatedLayout
desktopMenuItems={<MainDesktopMenu />}
mobileMenuItems={<MainMobileMenu />}
logo={<Logo className="w-10 h-10" />}
/>
}>
<Route path={paths.home} element={<Navigate to={paths.dashboard} />} />
<Route path={paths.dashboard} element={<Home />} />
<Route path={paths.profile} element={<Profile />} />
<Route path={paths.editName} element={<EditName />} />
<Route path={paths.editEmail} element={<EditEmail />} />
<Route path={paths.changePassword} element={<ChangePassword />} />
<Route path={paths.deleteAccount} element={<DeleteAccount />} />
<Route path={paths.createPlan} element={<CreatePlan />} />
</Route>
<Route path={paths.subscription} element={
<SubscriptionProvider>
<SubscriptionLayout
desktopMenu={<SubscriptionDesktopMenu />}
mobileMenu={<SubscriptionMobileMenu />}
logo={<Logo className="w-10 h-10" />}
/>
</SubscriptionProvider>
}>
<Route index element={
<ProtectedSubscriptionRoute requiredPermissions={['access']}>
<SubscriptionDashboard />
</ProtectedSubscriptionRoute>
} />
<Route path={paths.users} element={
<ProtectedSubscriptionRoute requiredPermissions={['admin']}>
<UserList />
</ProtectedSubscriptionRoute>
} />
<Route path={paths.invite} element={
<ProtectedSubscriptionRoute requiredPermissions={['admin']}>
<InviteUser />
</ProtectedSubscriptionRoute>
} />
<Route path={paths.billing} element={
<ProtectedSubscriptionRoute requiredPermissions={['admin']}>
<Billing />
</ProtectedSubscriptionRoute>
} />
<Route path={paths.settings} element={
<ProtectedSubscriptionRoute requiredPermissions={['admin']}>
<SubscriptionSettings />
</ProtectedSubscriptionRoute>
} />
<Route path={paths.changePlan} element={
<ProtectedSubscriptionRoute requiredPermissions={['owner']}>
<ChangePlan />
</ProtectedSubscriptionRoute>
} />
<Route path={paths.cancelSubscription} element={
<ProtectedSubscriptionRoute requiredPermissions={['owner']}>
<CancelSubscription />
</ProtectedSubscriptionRoute>
} />
<Route path={paths.managePaymentMethods} element={
<ProtectedSubscriptionRoute requiredPermissions={['owner']}>
<ManagePaymentMethods />
</ProtectedSubscriptionRoute>
} />
<Route path={paths.updateBillingDetails} element={
<ProtectedSubscriptionRoute requiredPermissions={['owner']}>
<UpdateBillingDetails />
</ProtectedSubscriptionRoute>
} />
<Route path={paths.transferOwnership} element={
<ProtectedSubscriptionRoute requiredPermissions={['owner']}>
<TransferSubscriptionOwnership />
</ProtectedSubscriptionRoute>
} />
</Route>
<Route element={<PublicLayout logo={<Logo className="w-20 h-20" />} />}>
<Route path={paths.signIn} element={<SignIn />} />
<Route path={paths.signUp} element={<SignUp />} />
<Route path={paths.resetPassword} element={<ResetPassword />} />
</Route>
</Routes>
</LoadingProvider>
</AuthProvider>
</ConfigProvider>
</Router>
);
}
export default App;
Follow the instructions (https://www.npmjs.com/package/@fireact.dev/saas-cloud-functions) to install the cloud functions
MIT
FAQs
A comprehensive SaaS toolkit for Firebase applications, featuring subscription management, billing integration, and user management components. Built on top of @fireact.dev/core with TailwindCSS styling.
The npm package @fireact.dev/saas receives a total of 66 weekly downloads. As such, @fireact.dev/saas popularity was classified as not popular.
We found that @fireact.dev/saas demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
Security News
A Stanford study reveals 9.5% of engineers contribute almost nothing, costing tech $90B annually, with remote work fueling the rise of "ghost engineers."
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.