Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
3c671d7
add firebase to next-client
nishkohli96 Apr 23, 2025
4b6d76e
move graphql into services in next-client
nishkohli96 Apr 23, 2025
2897934
i18n code moved into services
nishkohli96 Apr 23, 2025
a42ecd0
fix graphql errs in next-client
nishkohli96 Apr 23, 2025
d94ac41
initialize analytics instance wip
nishkohli96 Apr 23, 2025
5e23651
initialize in service
nishkohli96 Apr 23, 2025
a5280b4
firebase almost done
nishkohli96 Apr 24, 2025
5c06ea5
format firebase docs
nishkohli96 Apr 24, 2025
0247143
firebase analytics done
nishkohli96 Apr 24, 2025
d8240c7
firebase wip
nishkohli96 Apr 24, 2025
f4fa05c
firebas sign in ui wip
nishkohli96 Apr 27, 2025
41ec580
firebase sign in ui done
nishkohli96 Apr 27, 2025
be6ba98
firebase ui code
nishkohli96 Apr 27, 2025
2272ce8
add firebase in react-client
nish-appinventiv Sep 19, 2025
2de0cd9
update firebase.md
nishkohli96 Oct 7, 2025
b25c8fa
Merge branch 'firebase' of github.com:nishkohli96/client-server-libs …
nish-appinventiv Oct 7, 2025
45d2e8b
firebase setup for react-app
nish-appinventiv Oct 7, 2025
49c7cd7
trigger firebase notifs for chrome
nish-appinventiv Oct 7, 2025
862bcc1
getBrowser fn
nish-appinventiv Oct 7, 2025
2cb74f8
update firebase.ts
nish-appinventiv Oct 7, 2025
57352b9
add notif bell for safari
nish-appinventiv Oct 7, 2025
48cc993
send test notif from backend to chrome browser
nish-appinventiv Oct 7, 2025
29747f9
sample code done for safari
nish-appinventiv Oct 8, 2025
6d566d4
def browser utils in shared-fe
nishkohli96 Nov 4, 2025
322d271
install ua-parser-js
nishkohli96 Nov 4, 2025
c79e4da
fix conflicts
nishkohli96 Nov 5, 2025
26fb0d8
upgarde express to v5, multer to v2
nishkohli96 Nov 5, 2025
e1b1485
wip
nishkohli96 Nov 5, 2025
b7c64f8
upgrade graphql-server dependencies
nishkohli96 Nov 5, 2025
44cb34c
fix express server build err
nishkohli96 Nov 6, 2025
55fbf54
wip
nishkohli96 Nov 6, 2025
938facf
rm uploadcare
nishkohli96 Nov 6, 2025
a8298cc
fix next-client build err
nishkohli96 Nov 6, 2025
e366ee5
uncomment docker-img
nishkohli96 Nov 6, 2025
f22b704
comment nestjs docker img
nishkohli96 Nov 6, 2025
492fa64
downgrade lint staged
nishkohli96 Nov 6, 2025
344d3e6
get Browser info using ua-browser-js
nishkohli96 Nov 6, 2025
99dfa16
add setup.sh script
nishkohli96 Nov 6, 2025
2014b54
def firebase env vars in react and next client
nishkohli96 Nov 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .github/docker-img.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Publish Docker Images

on: [push]
# on:
# push:
# branches:
# - 'main'

env:
HUSKY: 0

jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Get current date
id: date
run: echo "::set-output name=date::$(date +'%Y_%m_%d_%H_%m')"

- name: Build Express Server Image
run: docker build -f ./apps/express-server/Dockerfile -t ${{secrets.DOCKER_HUB_USERNAME}}/csl-express-server:${{ steps.date.outputs.date }} .

- name: Build NestJS Server Image
run: docker build -f ./apps/nestjs-server/Dockerfile -t ${{secrets.DOCKER_HUB_USERNAME}}/csl-nestjs-server:${{ steps.date.outputs.date }} .

- name: Build Next Client Image
run: docker build -f ./apps/next-client/Dockerfile -t ${{ secrets.DOCKER_HUB_USERNAME }}/csl-next-client:${{ steps.date.outputs.date }} .

- name: Build React Client Image
run: docker build -f ./apps/react-client/Dockerfile -t ${{ secrets.DOCKER_HUB_USERNAME }}/csl-next-client:${{ steps.date.outputs.date }} .

- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}

- name: Push Express Server Image to Docker Hub
run: docker push ${{ secrets.DOCKER_HUB_USERNAME }}/csl-express-server:${{ steps.date.outputs.date }}

- name: Push NestJS Server Image to Docker Hub
run: docker push ${{ secrets.DOCKER_HUB_USERNAME }}/csl-nestjs-server:${{ steps.date.outputs.date }}

- name: Push Next Client Image to Docker Hub
run: docker push ${{ secrets.DOCKER_HUB_USERNAME }}/csl-next-client:${{ steps.date.outputs.date }}

- name: Push React Client Image to Docker Hub
run: docker push ${{ secrets.DOCKER_HUB_USERNAME }}/csl-react-client:${{ steps.date.outputs.date }}
59 changes: 0 additions & 59 deletions .github/workflows/docker-img.yml

This file was deleted.

3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ coverage
!.vscode/launch.json
!.vscode/extensions.json

# misc
# express-server
apps/express-server/public
apps/express-server/uploads
apps/express-server/src/firebase/service-account.json

# config files for migrations
apps/mysql-migrations/config/config.json
Expand Down
22 changes: 10 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,26 @@

The code for shared packages are in the `packages` folder & the applications code in the `apps` folder.

Install `node_modules`
Run the `setup.sh` script.

```bash
yarn
sh setup.sh
```

Due to some issues with `express` dependencies, you also need to run
This will perform the following tasks:

```
npm dedupe
```
- Install `node_modules` in workspace root
- Build the `@csl/mongo-models`, `@csl/react-express` and `@csl/shared-fe` packages.
- Link these packages to the respective applications in the `apps` directory.

to scan your `node_modules` and moves dependencies up in the tree if different versions can be consolidated. Delete the `package-lock.json` after running this command.

Build, run, lint or test all your apps in one command thanks to [Turborepo's Pipelines](https://turborepo.org/docs/core-concepts/pipelines)

To build all the shared packages,
To apply any changes made in the shared packages, rebuild them by running the command below:

```bash
turbo lib:build
yarn lib
```

Build, run, lint or test all your apps in one command thanks to [Turborepo's Pipelines](https://turborepo.org/docs/core-concepts/pipelines)

Each of the applications have common scripts which can be easily executed in parallel by turborepo's pipelines. Add these in `turbo.json`.

| Command | Result |
Expand Down
5 changes: 4 additions & 1 deletion apps/express-server/.env_sample
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,7 @@ AWS_SQS_FIFO_URL=
AWS_SNS_TOPIC_ARN=

# Stripe
STRIPE_SECRET_KEY=
STRIPE_SECRET_KEY=

# Firebase
FIREBASE_API_KEY=
20 changes: 10 additions & 10 deletions apps/express-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,28 @@
"@aws-sdk/client-iam": "^3.787.0",
"@aws-sdk/client-lambda": "3.787.0",
"@aws-sdk/client-s3": "^3.787.0",
"@aws-sdk/client-secrets-manager": "^3.787.0",
"@aws-sdk/client-ses": "^3.787.0",
"@aws-sdk/client-sns": "^3.787.0",
"@aws-sdk/client-sqs": "^3.787.0",
"@aws-sdk/client-ssm": "^3.787.0",
"@aws-sdk/client-secrets-manager": "^3.787.0",
"@aws-sdk/s3-request-presigner": "^3.787.0",
"@csl/mongo-models": "*",
"@csl/react-express": "*",
"@sentry/cli": "^2.43.0",
"@sentry/node": "^9.13.0",
"@sentry/profiling-node": "^9.13.0",
"apn": "^2.2.0",
"cors": "^2.8.5",
"csv-parser": "^3.2.0",
"dotenv": "^16.5.0",
"dd-trace": "^5.48.1",
"express": "^4.21.2",
"dotenv": "^16.5.0",
"express": "^5.1.0",
"firebase-admin": "^13.5.0",
"fluent-ffmpeg": "^2.1.3",
"ioredis": "^5.6.1",
"mixpanel": "^0.18.1",
"moment": "^2.30.1",
"mongoose": "^8.13.2",
"multer": "^1.4.5-lts.2",
"multer": "^2.0.2",
"mysql2": "^3.14.0",
"papaparse": "^5.5.2",
"pg": "^8.15.1",
Expand All @@ -48,6 +48,7 @@
"socket.io": "^4.8.1",
"stripe": "^18.0.0",
"stytch": "^12.17.0",
"ua-parser-js": "^2.0.6",
"uuid": "^11.1.0",
"winston": "3.17.0"
},
Expand All @@ -56,12 +57,11 @@
"@nish1896/eslint-flat-config": "^3.0.3",
"@sentry/cli": "^2.43.0",
"@types/cors": "^2.8.17",
"@types/express": "4.17.21",
"@types/express-serve-static-core": "^4.17.33",
"@types/express": "^5.0.5",
"@types/fluent-ffmpeg": "^2.1.27",
"@types/multer": "1.4.12",
"@types/multer": "2.0.0",
"@types/node": "^22.14.1",
"@types/papaparse":"^5.3.15",
"@types/papaparse": "^5.3.15",
"@types/uuid": "^10.0.0",
"env-cmd": "^10.1.0",
"eslint": "^9.25.1",
Expand Down
21 changes: 20 additions & 1 deletion apps/express-server/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import { ENV_VARS, ServerConfig } from '@/constants';
import { requestLogger } from '@/middleware';
import { routesArray } from '@/routes';
import { io } from '.';

import { sendSafariNotification } from '@/firebase/apns';
import { sendFCMNotification } from './firebase/fcm';
const app = express();

function generatePath(routeName: string): string {
Expand Down Expand Up @@ -62,6 +63,24 @@ app.get('/debug-sentry', function mainHandler() {
throw new Error('My first Sentry error!');
});

// sendSafariNotification(
// 'eQ5dYEavCKvGtvYrgJ0oLf:APA91bG1lOfYjB13MCCxVj6aZYi9mjf28h4KfUqLFxMOw_MsFzHCRqZi3ewLutwfQzcrMmmDTf4C_R4Zo87udDtnCjvcP7hrHHAEp3gTIdXglBFXTV1B1QY',
// 'Hello from APNs',
// 'This is a test notification sent via APNs',
// 'https://57f50d0eb427.ngrok-free.app'
// ).then(() => {
// console.log('Safari notification sent (if device token is valid)');
// }).catch(err => {
// console.error('Error sending Safari notification:', err);
// });

sendFCMNotification(
'eQ5dYEavCKvGtvYrgJ0oLf:APA91bG1lOfYjB13MCCxVj6aZYi9mjf28h4KfUqLFxMOw_MsFzHCRqZi3ewLutwfQzcrMmmDTf4C_R4Zo87udDtnCjvcP7hrHHAEp3gTIdXglBFXTV1B1QY',
'Hello from FCM in safari',
'This is a test notification sent via FCM',
{ customData: 'your_custom_data' }
);

/* 404 Handler */
app.get('*', (req: Request, response: Response) => {
const notFoundMsg = `Not Found - "${req.originalUrl}"`;
Expand Down
2 changes: 1 addition & 1 deletion apps/express-server/src/constants/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function defEnvVariable(varName: string, defaultValue?: string): string {
if (defaultValue) {
return defaultValue.trim();
}
throw new Error(`Missing required environment variable: ${varName}`);
throw new Error(`Missing environment variable: ${varName}`);
}

export const ENV_VARS = Object.freeze({
Expand Down
Empty file.
Binary file added apps/express-server/src/firebase/ReelQA.p12
Binary file not shown.
Binary file added apps/express-server/src/firebase/ReelTrak_QA.p12
Binary file not shown.
36 changes: 36 additions & 0 deletions apps/express-server/src/firebase/apns.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import apn from 'apn';
import path from 'path';

// Replace with your .p12 certificate for Safari Push
const options: apn.ProviderOptions = {
pfx: path.resolve(__dirname, 'ReelQA.p12'),
passphrase: '12345',
production: true, // true for production
};

const apnProvider = new apn.Provider(options);

/**
* Send Safari push notification
*/
export const sendSafariNotification = async (
deviceToken: string,
title: string,
body: string,
url: string
) => {
const note = new apn.Notification();
note.alert = { title, body };
note.urlArgs = [url];
note.topic = 'web.in.appskeeper.reelsfrontqa';
note.payload = { customData: 'your_custom_data' };
note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expires in 1 hour
note.priority = 10; // Immediate delivery

try {
const result = await apnProvider.send(note, deviceToken);
console.log('APNs Result:', JSON.stringify(result, null, 2));
} catch (err) {
console.error('APNs Error:', err);
}
};
46 changes: 46 additions & 0 deletions apps/express-server/src/firebase/fcm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import admin from 'firebase-admin';
import { type Message } from 'firebase-admin/lib/messaging';
import path from 'path';

const serviceAccount = path.resolve(__dirname, 'service-account.json');

if (!admin.apps.length) {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
});
}

/* Send notification to FCM token(s) */
export const sendFCMNotification = async (
token: string,
title: string,
body: string,
data: Record<string, string> = {}
) => {

const message = {
notification: { title, body },
tokens: [token], // send to all saved tokens
};

try {
const response = await admin.messaging().sendEachForMulticast(message);
console.log('response: ', response);
// res.json({ successCount: response.successCount, failureCount: response.failureCount });
} catch (err) {
console.error('Error sending message:', err);
// res.status(500).json({ error: err.message });
}
// const message: Message = {
// notification: { title, body },
// data,
// token,
// };

// try {
// const response = await admin.messaging().send(message);
// console.log('FCM Response:', response);
// } catch (err) {
// console.error('FCM Error:', err);
// }
};
Loading