├── package.json ├── server ├── .gitignore ├── src │ ├── routers │ │ ├── schema.ts │ │ ├── user.ts │ │ ├── auth.ts │ │ └── password.ts │ ├── config │ │ ├── emailConfig.ts │ │ └── dbConnect.ts │ ├── utils │ │ ├── template.ts │ │ ├── auth.ts │ │ └── encryption.ts │ ├── services │ │ ├── user.ts │ │ └── passwords.ts │ ├── controllers │ │ ├── user.ts │ │ ├── auth.ts │ │ └── password.ts │ ├── templates │ │ └── passwordReset.html │ ├── middlewares │ │ └── auth.ts │ ├── models │ │ └── schemas.ts │ └── index.ts ├── dist │ ├── routers │ │ ├── user.js.map │ │ ├── schema.js.map │ │ ├── auth.js.map │ │ ├── password.js.map │ │ ├── schema.js │ │ ├── user.js │ │ ├── auth.js │ │ └── password.js │ ├── config │ │ ├── emailConfig.js.map │ │ ├── emailConfig.js │ │ ├── dbConnect.js.map │ │ └── dbConnect.js │ ├── controllers │ │ ├── user.js.map │ │ ├── user.js │ │ ├── auth.js.map │ │ ├── password.js.map │ │ └── auth.js │ ├── utils │ │ ├── template.js.map │ │ ├── auth.js.map │ │ ├── template.js │ │ ├── encryption.js.map │ │ ├── auth.js │ │ └── encryption.js │ ├── services │ │ ├── user.js.map │ │ ├── passwords.js.map │ │ ├── user.js │ │ └── passwords.js │ ├── models │ │ ├── schemas.js.map │ │ └── schemas.js │ ├── middlewares │ │ ├── auth.js.map │ │ └── auth.js │ ├── index.js.map │ └── index.js ├── vercel.json ├── .env.example ├── tsconfig.json └── package.json ├── client ├── app │ ├── loading.tsx │ ├── dashboard │ │ ├── loading.tsx │ │ └── layout.tsx │ ├── layout.tsx │ └── globals.css ├── public │ ├── placeholder.jpg │ ├── placeholder-logo.png │ ├── placeholder-user.jpg │ ├── placeholder-logo.svg │ └── placeholder.svg ├── pnpm-lock.yaml ├── postcss.config.mjs ├── lib │ └── utils.ts ├── next.config.mjs ├── store │ ├── AuthStore │ │ └── index.ts │ └── ProfileStore │ │ └── index.ts ├── components │ ├── ui │ │ ├── skeleton.tsx │ │ ├── use-mobile.tsx │ │ ├── label.tsx │ │ ├── textarea.tsx │ │ ├── input.tsx │ │ ├── progress.tsx │ │ ├── separator.tsx │ │ ├── toaster.tsx │ │ ├── sonner.tsx │ │ ├── slider.tsx │ │ ├── switch.tsx │ │ ├── badge.tsx │ │ ├── tooltip.tsx │ │ ├── hover-card.tsx │ │ ├── popover.tsx │ │ ├── alert.tsx │ │ ├── radio-group.tsx │ │ ├── toggle.tsx │ │ ├── scroll-area.tsx │ │ ├── toggle-group.tsx │ │ ├── tabs.tsx │ │ ├── button.tsx │ │ ├── card.tsx │ │ ├── pagination.tsx │ │ ├── table.tsx │ │ ├── dialog.tsx │ │ ├── sheet.tsx │ │ ├── use-toast.ts │ │ ├── toast.tsx │ │ ├── navigation-menu.tsx │ │ └── select.tsx │ ├── theme-provider.tsx │ ├── hoc │ │ └── AuthHoc │ │ │ └── index.tsx │ ├── password-strength.tsx │ └── password-generator.tsx ├── services │ ├── ProfileService │ │ └── index.ts │ ├── AuthService │ │ └── index.ts │ ├── PasswordService │ │ └── index.ts │ └── request.ts ├── .gitignore ├── components.json ├── hooks │ ├── use-mobile.tsx │ ├── useAuth │ │ └── index.ts │ ├── use-icon-cache.ts │ ├── useFetch │ │ └── index.ts │ └── use-toast.ts ├── tsconfig.json ├── utils │ ├── Decrypty.ts │ └── icon-utils.ts ├── package.json ├── styles │ └── globals.css └── tailwind.config.ts ├── .github ├── workflows │ └── greetings.yaml └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── contribution.md ├── README.md └── CODE_OF_CONDUCT.md /package.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /server/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env -------------------------------------------------------------------------------- /client/app/loading.tsx: -------------------------------------------------------------------------------- 1 | export default function Loading() { 2 | return null 3 | } 4 | -------------------------------------------------------------------------------- /client/app/dashboard/loading.tsx: -------------------------------------------------------------------------------- 1 | export default function Loading() { 2 | return null 3 | } 4 | -------------------------------------------------------------------------------- /client/public/placeholder.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abhijeetnishal/Password-Shield/HEAD/client/public/placeholder.jpg -------------------------------------------------------------------------------- /client/pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false -------------------------------------------------------------------------------- /client/public/placeholder-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abhijeetnishal/Password-Shield/HEAD/client/public/placeholder-logo.png -------------------------------------------------------------------------------- /client/public/placeholder-user.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abhijeetnishal/Password-Shield/HEAD/client/public/placeholder-user.jpg -------------------------------------------------------------------------------- /client/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /client/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { clsx, type ClassValue } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /server/src/routers/schema.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import createSchemas from "../models/schemas"; 3 | 4 | const schemaRouter = express.Router(); 5 | 6 | // Endpoint for creating schemas. 7 | schemaRouter.post("/schema", createSchemas); 8 | 9 | export default schemaRouter; 10 | -------------------------------------------------------------------------------- /server/dist/routers/user.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/routers/user.ts"],"names":[],"mappings":";;;;;;AAAA,sDAA8B;AAC9B,8CAA2D;AAC3D,+DAAkD;AAElD,MAAM,UAAU,GAAG,iBAAO,CAAC,MAAM,EAAE,CAAC;AAI3B,gCAAU;AAFnB,UAAU,CAAC,GAAG,CAAC,eAAe,EAAE,cAAe,EAAE,2BAAoB,CAAC,CAAC"} -------------------------------------------------------------------------------- /server/dist/routers/schema.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/routers/schema.ts"],"names":[],"mappings":";;;;;AAAA,sDAA8B;AAC9B,gEAA8C;AAE9C,MAAM,YAAY,GAAG,iBAAO,CAAC,MAAM,EAAE,CAAC;AAEtC,iCAAiC;AACjC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAa,CAAC,CAAC;AAE5C,kBAAe,YAAY,CAAC"} -------------------------------------------------------------------------------- /client/app/dashboard/layout.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { AuthHoc } from "@/components/hoc/AuthHoc"; 4 | 5 | interface LayoutProps { 6 | children: React.ReactNode; 7 | } 8 | 9 | export default function DashboardLayout({ children }: LayoutProps) { 10 | return {children}; 11 | } 12 | -------------------------------------------------------------------------------- /client/next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | eslint: { 4 | ignoreDuringBuilds: true, 5 | }, 6 | typescript: { 7 | ignoreBuildErrors: true, 8 | }, 9 | images: { 10 | unoptimized: true, 11 | }, 12 | } 13 | 14 | export default nextConfig 15 | -------------------------------------------------------------------------------- /server/vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "builds": [ 4 | { 5 | "src": "dist/index.js", 6 | "use": "@vercel/node", 7 | "config": { "includeFiles": ["dist/**"] } 8 | } 9 | ], 10 | "routes": [ 11 | { 12 | "src": "/(.*)", 13 | "dest": "dist/index.js" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /client/store/AuthStore/index.ts: -------------------------------------------------------------------------------- 1 | import { create } from "zustand"; 2 | 3 | interface AuthStoreState { 4 | authToken: string; 5 | setAuthToken: Function; 6 | } 7 | 8 | export const useAuthStore = create((set) => ({ 9 | authToken: "", 10 | 11 | setAuthToken: (token: string) => set({ authToken: token }), 12 | })); 13 | -------------------------------------------------------------------------------- /server/src/routers/user.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import { getUserVerifyDetails } from "../controllers/user"; 3 | import isAuthenticated from "../middlewares/auth"; 4 | 5 | const userRouter = express.Router(); 6 | 7 | userRouter.get("/users/verify", isAuthenticated, getUserVerifyDetails); 8 | 9 | export { userRouter }; 10 | -------------------------------------------------------------------------------- /client/components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils" 2 | 3 | function Skeleton({ 4 | className, 5 | ...props 6 | }: React.HTMLAttributes) { 7 | return ( 8 |
12 | ) 13 | } 14 | 15 | export { Skeleton } 16 | -------------------------------------------------------------------------------- /client/services/ProfileService/index.ts: -------------------------------------------------------------------------------- 1 | import { request } from "../request"; 2 | 3 | const getUserVerifyDetails = (token: string) => { 4 | return request({ 5 | url: `/api/v1/users/verify`, 6 | method: "GET", 7 | headers: { "auth-token": token }, 8 | }); 9 | }; 10 | 11 | export const ProfileService = { 12 | getUserVerifyDetails, 13 | }; 14 | -------------------------------------------------------------------------------- /client/components/theme-provider.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import * as React from 'react' 4 | import { 5 | ThemeProvider as NextThemesProvider, 6 | type ThemeProviderProps, 7 | } from 'next-themes' 8 | 9 | export function ThemeProvider({ children, ...props }: ThemeProviderProps) { 10 | return {children} 11 | } 12 | -------------------------------------------------------------------------------- /client/store/ProfileStore/index.ts: -------------------------------------------------------------------------------- 1 | import { create } from "zustand"; 2 | 3 | interface ProfileStoreState { 4 | profileDetails: any; 5 | setProfileDetails: Function; 6 | } 7 | 8 | export const useProfileStore = create((set) => ({ 9 | profileDetails: {}, 10 | setProfileDetails: (userDetails: Object) => 11 | set({ profileDetails: userDetails }), 12 | })); 13 | -------------------------------------------------------------------------------- /client/components/hoc/AuthHoc/index.tsx: -------------------------------------------------------------------------------- 1 | import useAuth from "@/hooks/useAuth"; 2 | import { getCookie } from "cookies-next"; 3 | 4 | export const AuthHoc = ({ 5 | children, 6 | }: Readonly<{ 7 | children: React.ReactNode; 8 | }>) => { 9 | useAuth({ 10 | redirectTo: "/auth", 11 | token: getCookie("token") as string, 12 | }); 13 | 14 | return
{children}
; 15 | }; 16 | -------------------------------------------------------------------------------- /server/.env.example: -------------------------------------------------------------------------------- 1 | # environment 2 | NODE_ENV=development 3 | CLIENT_PROD_URL=http://localhost:3000 4 | 5 | # setup your postgres 6 | DATABASE_USER= 7 | DATABASE_PASSWORD= 8 | DATABASE_HOST= 9 | DATABASE_PORT= 10 | DATABASE_NAME= 11 | 12 | # keys used for encryption/authentication 13 | JWT_SECRET_KEY= 14 | PRIVATE_KEY= 15 | 16 | # keys used for email service 17 | GMAIL_ID= 18 | GMAIL_APP_PASSWORD= -------------------------------------------------------------------------------- /server/src/config/emailConfig.ts: -------------------------------------------------------------------------------- 1 | import nodemailer from "nodemailer"; 2 | import dotenv from "dotenv"; 3 | 4 | dotenv.config(); 5 | 6 | // Configure nodemailer transporter 7 | const transporter = nodemailer.createTransport({ 8 | service: "Gmail", 9 | auth: { 10 | user: process.env.GMAIL_ID, 11 | pass: process.env.GMAIL_APP_PASSWORD, 12 | }, 13 | }); 14 | 15 | export { transporter }; 16 | -------------------------------------------------------------------------------- /server/dist/config/emailConfig.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"emailConfig.js","sourceRoot":"","sources":["../../src/config/emailConfig.ts"],"names":[],"mappings":";;;;;;AAAA,4DAAoC;AACpC,oDAA4B;AAE5B,gBAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,mCAAmC;AACnC,MAAM,WAAW,GAAG,oBAAU,CAAC,eAAe,CAAC;IAC7C,OAAO,EAAE,OAAO;IAChB,IAAI,EAAE;QACJ,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ;QAC1B,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB;KACrC;CACF,CAAC,CAAC;AAEM,kCAAW"} -------------------------------------------------------------------------------- /server/src/utils/template.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | 3 | // Function to read the HTML template 4 | function getHtmlTemplate(filePath: string, replacements: any) { 5 | let html = fs.readFileSync(filePath, "utf8"); 6 | 7 | for (const key in replacements) { 8 | html = html.replace(new RegExp(`{{${key}}}`, "g"), replacements[key]); 9 | } 10 | 11 | return html; 12 | } 13 | 14 | export { getHtmlTemplate }; 15 | -------------------------------------------------------------------------------- /client/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import "./globals.css"; 3 | 4 | export const metadata: Metadata = { 5 | title: "Password Shield App", 6 | description: "", 7 | }; 8 | 9 | export default function RootLayout({ 10 | children, 11 | }: Readonly<{ 12 | children: React.ReactNode; 13 | }>) { 14 | return ( 15 | 16 | {children} 17 | 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /server/dist/controllers/user.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/controllers/user.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,2CAA8C;AAO9C,MAAM,oBAAoB,GAAG,CAC3B,GAAyB,EACzB,GAAa,EACb,EAAE;IACF,MAAM,IAAI,GAAG,MAAM,IAAA,iBAAU,EAAC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IAE9C,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;AACvE,CAAC,CAAA,CAAC;AAEO,oDAAoB"} -------------------------------------------------------------------------------- /client/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # next.js 7 | /.next/ 8 | /out/ 9 | 10 | # production 11 | /build 12 | 13 | # debug 14 | npm-debug.log* 15 | yarn-debug.log* 16 | yarn-error.log* 17 | .pnpm-debug.log* 18 | 19 | # env files 20 | .env* 21 | 22 | # vercel 23 | .vercel 24 | 25 | # typescript 26 | *.tsbuildinfo 27 | next-env.d.ts -------------------------------------------------------------------------------- /server/dist/routers/auth.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/routers/auth.ts"],"names":[],"mappings":";;;;;AAAA,sDAA8B;AAC9B,8CAK6B;AAC7B,+DAAkD;AAElD,MAAM,UAAU,GAAG,iBAAO,CAAC,MAAM,EAAE,CAAC;AAEpC,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,eAAQ,CAAC,CAAC;AAEvC,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAK,CAAC,CAAC;AAEjC,UAAU,CAAC,IAAI,CAAC,kBAAkB,EAAE,qBAAc,CAAC,CAAC;AAEpD,UAAU,CAAC,IAAI,CAAC,iBAAiB,EAAE,cAAe,EAAE,oBAAa,CAAC,CAAC;AAEnE,kBAAe,UAAU,CAAC"} -------------------------------------------------------------------------------- /server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "esModuleInterop": true, 5 | "allowSyntheticDefaultImports": true, 6 | "target": "es6", 7 | "noImplicitAny": true, 8 | "moduleResolution": "node", 9 | "sourceMap": true, 10 | "outDir": "dist", 11 | "baseUrl": ".", 12 | "paths": { 13 | "*": ["node_modules/*", "src/types/*"] 14 | } 15 | }, 16 | "include": ["./src/**/*"] 17 | } 18 | -------------------------------------------------------------------------------- /server/dist/utils/template.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/utils/template.ts"],"names":[],"mappings":";;;;;;AAAA,4CAAoB;AAEpB,qCAAqC;AACrC,SAAS,eAAe,CAAC,QAAgB,EAAE,YAAiB;IAC1D,IAAI,IAAI,GAAG,YAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAE7C,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE;QAC9B,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;KACvE;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAEQ,0CAAe"} -------------------------------------------------------------------------------- /server/src/services/user.ts: -------------------------------------------------------------------------------- 1 | import { pool } from "../config/dbConnect"; 2 | 3 | const getDetails = async (queryKey: string, queryValue: string) => { 4 | try { 5 | const { rows } = await pool.query( 6 | `SELECT * FROM users WHERE ${queryKey} = $1`, 7 | [queryValue] 8 | ); 9 | 10 | const user = rows[0]; 11 | return user; 12 | } catch (error) { 13 | console.log(error); 14 | return null; 15 | } 16 | }; 17 | 18 | export { getDetails }; 19 | -------------------------------------------------------------------------------- /server/dist/routers/password.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"password.js","sourceRoot":"","sources":["../../src/routers/password.ts"],"names":[],"mappings":";;;;;AAAA,sDAA8B;AAC9B,+DAAkD;AAClD,sDAKiC;AAEjC,MAAM,cAAc,GAAG,iBAAO,CAAC,MAAM,EAAE,CAAC;AAExC,cAAc,CAAC,IAAI,CAAC,aAAa,EAAE,cAAe,EAAE,yBAAc,CAAC,CAAC;AAEpE,cAAc,CAAC,GAAG,CAAC,aAAa,EAAE,cAAe,EAAE,0BAAe,CAAC,CAAC;AAEpE,cAAc,CAAC,GAAG,CAAC,gBAAgB,EAAE,cAAe,EAAE,yBAAc,CAAC,CAAC;AAEtE,cAAc,CAAC,MAAM,CAAC,gBAAgB,EAAE,cAAe,EAAE,yBAAc,CAAC,CAAC;AAEzE,kBAAe,cAAc,CAAC"} -------------------------------------------------------------------------------- /server/dist/services/user.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/services/user.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,mDAA2C;AAE3C,MAAM,UAAU,GAAG,CAAO,QAAgB,EAAE,UAAkB,EAAE,EAAE;IAChE,IAAI;QACF,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,gBAAI,CAAC,KAAK,CAC/B,6BAA6B,QAAQ,OAAO,EAC5C,CAAC,UAAU,CAAC,CACb,CAAC;QAEF,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;KACb;IAAC,OAAO,KAAK,EAAE;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;KACb;AACH,CAAC,CAAA,CAAC;AAEO,gCAAU"} -------------------------------------------------------------------------------- /server/src/services/passwords.ts: -------------------------------------------------------------------------------- 1 | import { pool } from "../config/dbConnect"; 2 | 3 | const getPasswordDetails = async (queryKey: string, queryValue: string) => { 4 | try { 5 | const { rows } = await pool.query( 6 | `SELECT * FROM passwords WHERE ${queryKey} = $1`, 7 | [queryValue] 8 | ); 9 | 10 | const password = rows[0]; 11 | return password; 12 | } catch (error) { 13 | console.log(error); 14 | return null; 15 | } 16 | }; 17 | 18 | export { getPasswordDetails }; 19 | -------------------------------------------------------------------------------- /server/dist/services/passwords.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"passwords.js","sourceRoot":"","sources":["../../src/services/passwords.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,mDAA2C;AAE3C,MAAM,kBAAkB,GAAG,CAAO,QAAgB,EAAE,UAAkB,EAAE,EAAE;IACxE,IAAI;QACF,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,gBAAI,CAAC,KAAK,CAC/B,iCAAiC,QAAQ,OAAO,EAChD,CAAC,UAAU,CAAC,CACb,CAAC;QAEF,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACzB,OAAO,QAAQ,CAAC;KACjB;IAAC,OAAO,KAAK,EAAE;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;KACb;AACH,CAAC,CAAA,CAAC;AAEO,gDAAkB"} -------------------------------------------------------------------------------- /client/components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.ts", 8 | "css": "app/globals.css", 9 | "baseColor": "neutral", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | }, 20 | "iconLibrary": "lucide" 21 | } -------------------------------------------------------------------------------- /server/src/routers/auth.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import { 3 | register, 4 | login, 5 | forgotPassword, 6 | resetPassword, 7 | } from "../controllers/auth"; 8 | import isAuthenticated from "../middlewares/auth"; 9 | 10 | const authRouter = express.Router(); 11 | 12 | authRouter.post("/register", register); 13 | 14 | authRouter.post("/login", login); 15 | 16 | authRouter.post("/forgot-password", forgotPassword); 17 | 18 | authRouter.post("/reset-password", isAuthenticated, resetPassword); 19 | 20 | export default authRouter; 21 | -------------------------------------------------------------------------------- /server/dist/models/schemas.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/models/schemas.ts"],"names":[],"mappings":";;;;;;;;;;;AACA,mDAA2C;AAE3C,MAAM,aAAa,GAAG,CAAO,GAAY,EAAE,GAAa,EAAE,EAAE;IAC1D,IAAI;QACF,qBAAqB;QACrB,MAAM,gBAAI,CAAC,KAAK,CACd;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BC,CACF,CAAC;QAEF,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;KACvD;IAAC,OAAO,KAAK,EAAE;QACd,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;QAChD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;KAC/C;AACH,CAAC,CAAA,CAAC;AAEF,kBAAe,aAAa,CAAC"} -------------------------------------------------------------------------------- /server/dist/routers/schema.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | const express_1 = __importDefault(require("express")); 7 | const schemas_1 = __importDefault(require("../models/schemas")); 8 | const schemaRouter = express_1.default.Router(); 9 | // Endpoint for creating schemas. 10 | schemaRouter.post("/schema", schemas_1.default); 11 | exports.default = schemaRouter; 12 | //# sourceMappingURL=schema.js.map -------------------------------------------------------------------------------- /client/services/AuthService/index.ts: -------------------------------------------------------------------------------- 1 | import { request } from "../request"; 2 | 3 | interface AuthPayload { 4 | email?: string; 5 | password?: string; 6 | name?: string; 7 | } 8 | 9 | const signup = (payload: AuthPayload) => { 10 | return request({ 11 | url: `/auth/v1/register`, 12 | method: "POST", 13 | body: payload, 14 | }); 15 | }; 16 | 17 | const login = (payload: AuthPayload) => { 18 | return request({ 19 | url: `/auth/v1/login`, 20 | method: "POST", 21 | body: payload, 22 | }); 23 | }; 24 | 25 | export const AuthService = { 26 | signup, 27 | login, 28 | }; 29 | -------------------------------------------------------------------------------- /server/src/controllers/user.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response } from "express"; 2 | import { getDetails } from "../services/user"; 3 | 4 | // Define a custom interface that extends the Request interface with the _id property 5 | interface AuthenticatedRequest extends Request { 6 | _id?: string; // Make it optional or provide a default value if needed 7 | } 8 | 9 | const getUserVerifyDetails = async ( 10 | req: AuthenticatedRequest, 11 | res: Response 12 | ) => { 13 | const data = await getDetails("_id", req._id); 14 | 15 | return res.status(200).json({ data: data, message: "User details" }); 16 | }; 17 | 18 | export { getUserVerifyDetails }; 19 | -------------------------------------------------------------------------------- /.github/workflows/greetings.yaml: -------------------------------------------------------------------------------- 1 | name: Greetings 2 | 3 | on: [pull_request_target, issues] 4 | 5 | jobs: 6 | greeting: 7 | runs-on: ubuntu-latest 8 | permissions: 9 | issues: write 10 | pull-requests: write 11 | steps: 12 | - uses: actions/first-interaction@v1 13 | with: 14 | repo-token: ${{ secrets.GITHUB_TOKEN }} 15 | issue-message: "Hi there! Thanks for opening this issue. We appreciate your contribution to this open-source project. We aim to respond or assign your issue as soon as possible." 16 | pr-message: "Welcome to Our repository.🎊 Thank you so much for taking the time to point this out." 17 | -------------------------------------------------------------------------------- /server/dist/routers/user.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.userRouter = void 0; 7 | const express_1 = __importDefault(require("express")); 8 | const user_1 = require("../controllers/user"); 9 | const auth_1 = __importDefault(require("../middlewares/auth")); 10 | const userRouter = express_1.default.Router(); 11 | exports.userRouter = userRouter; 12 | userRouter.get("/users/verify", auth_1.default, user_1.getUserVerifyDetails); 13 | //# sourceMappingURL=user.js.map -------------------------------------------------------------------------------- /server/src/routers/password.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import isAuthenticated from "../middlewares/auth"; 3 | import { 4 | createPassword, 5 | deletePassword, 6 | getAllPasswords, 7 | updatePassword, 8 | } from "../controllers/password"; 9 | 10 | const passwordRouter = express.Router(); 11 | 12 | passwordRouter.post("/passwords/", isAuthenticated, createPassword); 13 | 14 | passwordRouter.get("/passwords/", isAuthenticated, getAllPasswords); 15 | 16 | passwordRouter.put("/passwords/:id", isAuthenticated, updatePassword); 17 | 18 | passwordRouter.delete("/passwords/:id", isAuthenticated, deletePassword); 19 | 20 | export default passwordRouter; 21 | -------------------------------------------------------------------------------- /client/components/ui/use-mobile.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | const MOBILE_BREAKPOINT = 768 4 | 5 | export function useIsMobile() { 6 | const [isMobile, setIsMobile] = React.useState(undefined) 7 | 8 | React.useEffect(() => { 9 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`) 10 | const onChange = () => { 11 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 12 | } 13 | mql.addEventListener("change", onChange) 14 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 15 | return () => mql.removeEventListener("change", onChange) 16 | }, []) 17 | 18 | return !!isMobile 19 | } 20 | -------------------------------------------------------------------------------- /server/dist/utils/auth.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":";;;;;;AAAA,gEAA+B;AAO/B,MAAM,gBAAgB,GAAG,CAAC,WAAgB,EAAE,UAA2B,EAAE,EAAE,EAAE;IAC3E,OAAO,sBAAG,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;AACpE,CAAC,CAAC;AAiBqB,4CAAgB;AAfvC,MAAM,cAAc,GAAG,CAAC,KAAa,EAAE,EAAE;IACvC,IAAI;QACF,OAAO,sBAAG,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,CAAiB,CAAC;KACtE;IAAC,OAAO,KAAK,EAAE;QACd,OAAO,KAAK,CAAC;KACd;AACH,CAAC,CAAC;AASuC,wCAAc;AAPvD,MAAM,YAAY,GAAG,CAAC,KAAa,EAAW,EAAE;IAC9C,kDAAkD;IAClD,MAAM,YAAY,GAAG,4BAA4B,CAAC;IAElD,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC,CAAC;AAEO,oCAAY"} -------------------------------------------------------------------------------- /client/hooks/use-mobile.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | const MOBILE_BREAKPOINT = 768; 4 | 5 | export function useIsMobile() { 6 | const [isMobile, setIsMobile] = React.useState( 7 | undefined 8 | ); 9 | 10 | React.useEffect(() => { 11 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`); 12 | const onChange = () => { 13 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT); 14 | }; 15 | mql.addEventListener("change", onChange); 16 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT); 17 | return () => mql.removeEventListener("change", onChange); 18 | }, []); 19 | 20 | return !!isMobile; 21 | } 22 | -------------------------------------------------------------------------------- /server/src/templates/passwordReset.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Password Reset 7 | 8 | 9 |

Hello,

10 |

11 | You have requested to reset your password. Please click the following link 12 | to reset your password: 13 |

14 |

15 | {{resetPasswordLink}} 16 |

17 |

If you did not request a password reset, please ignore this email.

18 |

Best regards,
Your App Name Team

19 | 20 | 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["dom", "dom.iterable", "esnext"], 4 | "allowJs": true, 5 | "target": "ES6", 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "noEmit": true, 9 | "esModuleInterop": true, 10 | "module": "esnext", 11 | "moduleResolution": "bundler", 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "jsx": "preserve", 15 | "incremental": true, 16 | "plugins": [ 17 | { 18 | "name": "next" 19 | } 20 | ], 21 | "paths": { 22 | "@/*": ["./*"] 23 | } 24 | }, 25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 26 | "exclude": ["node_modules"] 27 | } 28 | -------------------------------------------------------------------------------- /server/dist/utils/template.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.getHtmlTemplate = void 0; 7 | const fs_1 = __importDefault(require("fs")); 8 | // Function to read the HTML template 9 | function getHtmlTemplate(filePath, replacements) { 10 | let html = fs_1.default.readFileSync(filePath, "utf8"); 11 | for (const key in replacements) { 12 | html = html.replace(new RegExp(`{{${key}}}`, "g"), replacements[key]); 13 | } 14 | return html; 15 | } 16 | exports.getHtmlTemplate = getHtmlTemplate; 17 | //# sourceMappingURL=template.js.map -------------------------------------------------------------------------------- /server/dist/config/emailConfig.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.transporter = void 0; 7 | const nodemailer_1 = __importDefault(require("nodemailer")); 8 | const dotenv_1 = __importDefault(require("dotenv")); 9 | dotenv_1.default.config(); 10 | // Configure nodemailer transporter 11 | const transporter = nodemailer_1.default.createTransport({ 12 | service: "Gmail", 13 | auth: { 14 | user: process.env.GMAIL_ID, 15 | pass: process.env.GMAIL_APP_PASSWORD, 16 | }, 17 | }); 18 | exports.transporter = transporter; 19 | //# sourceMappingURL=emailConfig.js.map -------------------------------------------------------------------------------- /server/dist/routers/auth.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | const express_1 = __importDefault(require("express")); 7 | const auth_1 = require("../controllers/auth"); 8 | const auth_2 = __importDefault(require("../middlewares/auth")); 9 | const authRouter = express_1.default.Router(); 10 | authRouter.post("/register", auth_1.register); 11 | authRouter.post("/login", auth_1.login); 12 | authRouter.post("/forgot-password", auth_1.forgotPassword); 13 | authRouter.post("/reset-password", auth_2.default, auth_1.resetPassword); 14 | exports.default = authRouter; 15 | //# sourceMappingURL=auth.js.map -------------------------------------------------------------------------------- /server/src/utils/auth.ts: -------------------------------------------------------------------------------- 1 | import jwt from "jsonwebtoken"; 2 | 3 | // Define an interface for the decoded JWT payload 4 | interface DecodedToken { 5 | _id?: string; 6 | } 7 | 8 | const generateJWTToken = (userDetails: any, options: jwt.SignOptions = {}) => { 9 | return jwt.sign(userDetails, process.env.JWT_SECRET_KEY, options); 10 | }; 11 | 12 | const verifyJWTToken = (token: string) => { 13 | try { 14 | return jwt.verify(token, process.env.JWT_SECRET_KEY) as DecodedToken; 15 | } catch (error) { 16 | return false; 17 | } 18 | }; 19 | 20 | const isValidEmail = (email: string): boolean => { 21 | // Regular expression pattern for email validation 22 | const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; 23 | 24 | return emailPattern.test(email); 25 | }; 26 | 27 | export { isValidEmail, generateJWTToken, verifyJWTToken }; 28 | -------------------------------------------------------------------------------- /client/components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as LabelPrimitive from "@radix-ui/react-label" 5 | import { cva, type VariantProps } from "class-variance-authority" 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | const labelVariants = cva( 10 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 11 | ) 12 | 13 | const Label = React.forwardRef< 14 | React.ElementRef, 15 | React.ComponentPropsWithoutRef & 16 | VariantProps 17 | >(({ className, ...props }, ref) => ( 18 | 23 | )) 24 | Label.displayName = LabelPrimitive.Root.displayName 25 | 26 | export { Label } 27 | -------------------------------------------------------------------------------- /client/components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | export interface TextareaProps extends React.TextareaHTMLAttributes {} 6 | 7 | const Textarea = React.forwardRef(({ className, ...props }, ref) => { 8 | return ( 9 |