diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index aa016058..a2bcac4e 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -2,36 +2,41 @@
// https://github.com/microsoft/vscode-dev-containers/tree/v0.209.6/containers/javascript-node-postgres
// Update the VARIANT arg in docker-compose.yml to pick a Node.js version
{
+ "$schema": "https://raw.githubusercontent.com/devcontainers/spec/refs/heads/main/schemas/devContainer.schema.json",
"name": "bde-isima",
"dockerComposeFile": "docker-compose.yml",
"service": "bde_isima",
"workspaceFolder": "/workspace",
// Set *default* container specific settings.json values on container create.
- "settings": {
- "typescript.preferences.importModuleSpecifier": "non-relative",
- "typescript.tsdk": "node_modules/typescript/lib",
- "editor.defaultFormatter": "esbenp.prettier-vscode",
- "editor.formatOnSave": true,
- "editor.formatOnPaste": false,
- "editor.codeActionsOnSave": {
- "source.fixAll.eslint": true
- },
- "files.trimTrailingWhitespace": true
+ "customizations": {
+ "vscode": {
+ "settings": {
+ "typescript.preferences.importModuleSpecifier": "non-relative",
+ "typescript.tsdk": "node_modules/typescript/lib",
+ "editor.defaultFormatter": "esbenp.prettier-vscode",
+ "editor.formatOnSave": true,
+ "editor.formatOnPaste": false,
+ "editor.codeActionsOnSave": {
+ "source.fixAll.eslint": true
+ },
+ "files.trimTrailingWhitespace": true
+ },
+ // Add the IDs of extensions you want installed when the container is created.
+ "extensions": [
+ "ms-azuretools.vscode-docker",
+ "mikestead.dotenv",
+ "editorconfig.editorconfig",
+ "dbaeumer.vscode-eslint",
+ "graphql.vscode-graphql",
+ "ms-vscode.vscode-typescript-next",
+ "esbenp.prettier-vscode",
+ "mgmcdermott.vscode-language-babel",
+ "prisma.prisma",
+ "shardulm94.trailing-spaces",
+ "bradlc.vscode-tailwindcss"
+ ]
+ }
},
- // Add the IDs of extensions you want installed when the container is created.
- "extensions": [
- "ms-azuretools.vscode-docker",
- "mikestead.dotenv",
- "editorconfig.editorconfig",
- "dbaeumer.vscode-eslint",
- "graphql.vscode-graphql",
- "ms-vscode.vscode-typescript-next",
- "esbenp.prettier-vscode",
- "mgmcdermott.vscode-language-babel",
- "prisma.prisma",
- "shardulm94.trailing-spaces",
- "bradlc.vscode-tailwindcss"
- ],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [
3000
diff --git a/.env.template b/.env.template
index 9b637962..d6e31145 100644
--- a/.env.template
+++ b/.env.template
@@ -4,12 +4,7 @@ DATABASE_URL=postgresql://postgres:postgres@bde_isima_pg:5432/postgres
NEXT_PUBLIC_FRONTEND_URL=http://localhost:3000
NEXT_PUBLIC_GA_TRACKING_ID=REDACTED
-NEXT_PUBLIC_DISCORD_SERVER_URL=https://discord.gg/bnJ3narzF3
-
-LYF_API_VENDOR_ID=deebb957-9025-4894-b52d-24493cdb7278
-LYF_API_SECRET_KEY=B52DFC6C7F4AA054CDB08E38B2298C97A4A12039
-LYF_CREDIT_CARD_API_URL=https://sandbox-webpos.lyf.eu/fr/plugin/PaymentCb.aspx
-LYF_FROM_APPLICATION_API_URL=https://sandbox-webpos.lyf.eu/fr/plugin/Payment.aspx
+NEXT_PUBLIC_DISCORD_SERVER_URL=REDACTED
SESSION_SECRET_KEY=generate_on_https://randomkeygen.com
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 7256f21c..28511bd9 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -45,12 +45,9 @@ jobs:
envkey_CONTACT_MAIL: ${{ secrets.CONTACT_MAIL }}
envkey_DATABASE_URL: ${{ secrets.DATABASE_URL }}
envkey_SESSION_SECRET_KEY: ${{ secrets.SESSION_SECRET_KEY }}
- envkey_LYF_API_VENDOR_ID: ${{ secrets.LYF_API_VENDOR_ID }}
- envkey_LYF_API_SECRET_KEY: ${{ secrets.LYF_API_SECRET_KEY }}
- envkey_LYF_FROM_APPLICATION_API_URL: ${{ secrets.LYF_FROM_APPLICATION_API_URL }}
- envkey_LYF_CREDIT_CARD_API_URL: ${{ secrets.LYF_CREDIT_CARD_API_URL }}
envkey_NEXT_PUBLIC_FRONTEND_URL: ${{ secrets.NEXT_PUBLIC_FRONTEND_URL }}
envkey_NEXT_PUBLIC_GA_TRACKING_ID: ${{ secrets.NEXT_PUBLIC_GA_TRACKING_ID }}
+ envkey_NEXT_PUBLIC_DISCORD_SERVER_URL: ${{ secrets.NEXT_PUBLIC_DISCORD_SERVER_URL }}
envkey_SMTP_EMAIL: bde.isima.webmaster@gmail.com
envkey_SMTP_USER: bde.isima.webmaster
envkey_SMTP_HOST: ${{ secrets.SMTP_HOST }}
diff --git a/app/blitz-server.ts b/app/blitz-server.ts
index ec61602c..2dfcbedd 100644
--- a/app/blitz-server.ts
+++ b/app/blitz-server.ts
@@ -2,10 +2,15 @@ import db from 'db';
import { AuthServerPlugin, PrismaStorage, simpleRolesIsAuthorized } from '@blitzjs/auth';
import { setupBlitzServer } from '@blitzjs/next';
+import { BlitzLogger } from 'blitz';
import { authConfig } from 'app/blitz-client';
export const { gSSP, gSP, api } = setupBlitzServer({
+ logger: BlitzLogger({
+ minLevel: 'warn',
+ colorizePrettyLogs: true,
+ }),
plugins: [
AuthServerPlugin({
...authConfig,
diff --git a/app/components/dashboard/cashing/CashingDialog.tsx b/app/components/dashboard/cashing/CashingDialog.tsx
index 5dbc5589..21886a63 100644
--- a/app/components/dashboard/cashing/CashingDialog.tsx
+++ b/app/components/dashboard/cashing/CashingDialog.tsx
@@ -30,6 +30,7 @@ import { isTroll } from 'app/core/utils/listeux_or_troll';
import getTransactions from 'app/entities/transactions/queries/getTransactions';
import getUser from 'app/entities/users/queries/getUser';
import getUsers from 'app/entities/users/queries/getUsers';
+import Adherent from 'app/components/hub/transactions/display/Adherent';
const Catalog = lazy(() => import('./catalog/Catalog'));
const AdminTransfer = lazy(() => import('./adminTransfer/AdminTransfer'));
@@ -99,6 +100,10 @@ export default function CashingDialog({ user, onSelection, onClear }) {
+ }>
+
+
+
}>
diff --git a/app/components/dashboard/clubs/ClubForm.tsx b/app/components/dashboard/clubs/ClubForm.tsx
index c71cd50f..3ba0a051 100644
--- a/app/components/dashboard/clubs/ClubForm.tsx
+++ b/app/components/dashboard/clubs/ClubForm.tsx
@@ -2,7 +2,7 @@ import Divider from '@mui/material/Divider';
import IconButton from '@mui/material/IconButton';
import InputAdornment from '@mui/material/InputAdornment';
import { Club } from 'db';
-import { TextField } from 'mui-rff';
+import { Switches, TextField } from 'mui-rff';
import OpenInNew from '@mui/icons-material/OpenInNewTwoTone';
@@ -43,7 +43,8 @@ export default function ClubForm(props: ClubFormProps) {
facebookURL: props.initialValues?.facebookURL,
twitterURL: props.initialValues?.twitterURL,
instagramURL: props.initialValues?.instagramURL,
- customURL: props.initialValues?.customURL
+ customURL: props.initialValues?.customURL,
+ isPublic: props.initialValues?.isPublic
}}
onSubmit={onSubmit}
autoComplete="off"
@@ -84,6 +85,8 @@ export default function ClubForm(props: ClubFormProps) {
+
+
diff --git a/app/components/dashboard/partners/PartnerForm.tsx b/app/components/dashboard/partners/PartnerForm.tsx
index cbb6a189..47eac912 100644
--- a/app/components/dashboard/partners/PartnerForm.tsx
+++ b/app/components/dashboard/partners/PartnerForm.tsx
@@ -1,7 +1,7 @@
import IconButton from '@mui/material/IconButton';
import InputAdornment from '@mui/material/InputAdornment';
import { Partner } from 'db';
-import { TextField } from 'mui-rff';
+import { Switches, TextField } from 'mui-rff';
import OpenInNew from '@mui/icons-material/OpenInNewTwoTone';
@@ -37,7 +37,8 @@ export default function PartnerForm(props: PartnerFormProps) {
id: props.initialValues?.id,
image: props.initialValues?.image,
name: props.initialValues?.name,
- description: props.initialValues?.description
+ description: props.initialValues?.description,
+ isPublic: props.initialValues?.isPublic
}}
onSubmit={onSubmit}
autoComplete="off"
@@ -76,6 +77,8 @@ export default function PartnerForm(props: PartnerFormProps) {
+
+
);
}
diff --git a/app/components/forms/validations.ts b/app/components/forms/validations.ts
index fd8e6f23..877bccc0 100644
--- a/app/components/forms/validations.ts
+++ b/app/components/forms/validations.ts
@@ -77,7 +77,8 @@ export const ClubInput = z
facebookURL: z.string().url().optional().nullable(),
twitterURL: z.string().url().optional().nullable(),
instagramURL: z.string().url().optional().nullable(),
- customURL: z.string().url().optional().nullable()
+ customURL: z.string().url().optional().nullable(),
+ isPublic: z.boolean().optional().nullable()
})
.partial();
export type ClubInputType = z.infer;
@@ -113,7 +114,8 @@ export const PartnerInput = z
.optional()
.nullable(),
name: z.string().max(255),
- description: z.string().max(3000).optional().nullable()
+ description: z.string().max(3000).optional().nullable(),
+ isPublic: z.boolean().optional().nullable()
})
.partial();
export type PartnerInputType = z.infer;
diff --git a/app/components/hub/transactions/display/Adherent.tsx b/app/components/hub/transactions/display/Adherent.tsx
new file mode 100644
index 00000000..3045152f
--- /dev/null
+++ b/app/components/hub/transactions/display/Adherent.tsx
@@ -0,0 +1,20 @@
+import Typography, { TypographyTypeMap } from '@mui/material/Typography';
+
+import { useQuery } from '@blitzjs/rpc';
+
+type BalanceProps = {
+ getQuery: any;
+ queryArgs?: any;
+ variant?: TypographyTypeMap['props']['variant'];
+};
+
+export default function Adherent({ getQuery, queryArgs = {}, variant = 'h5' }: BalanceProps) {
+ const [user] = useQuery(getQuery, queryArgs);
+ const adherent = (user as any).is_member;
+
+ return (
+
+ {adherent ? 'Cotisant' : 'Non-Cotisant'}
+
+ );
+}
diff --git a/app/components/hub/transactions/display/TransactionsCard.tsx b/app/components/hub/transactions/display/TransactionsCard.tsx
index e1667c69..4d0b4a7b 100644
--- a/app/components/hub/transactions/display/TransactionsCard.tsx
+++ b/app/components/hub/transactions/display/TransactionsCard.tsx
@@ -1,6 +1,5 @@
import { Suspense } from 'react';
-import Badge from '@mui/material/Badge';
import Button from '@mui/material/Button';
import ButtonGroup from '@mui/material/ButtonGroup';
import Card from '@mui/material/Card';
@@ -9,7 +8,6 @@ import Typography from '@mui/material/Typography';
import CompareArrows from '@mui/icons-material/CompareArrowsTwoTone';
import History from '@mui/icons-material/HistoryTwoTone';
-import LocalAtm from '@mui/icons-material/LocalAtmTwoTone';
import { useAuthenticatedSession } from '@blitzjs/auth';
@@ -17,7 +15,7 @@ import Balance from 'app/components/hub/transactions/display/Balance';
import RecentTransactions from 'app/components/hub/transactions/display/RecentTransactions';
import getCurrentUser from 'app/entities/users/queries/getCurrentUser';
-export default function TransactionsCard({ openTransfer, openHistory, openTopUp }) {
+export default function TransactionsCard({ openTransfer, openHistory }) {
const session = useAuthenticatedSession();
const FallbackComponent = [...Array(10).keys()].map((x) => (
@@ -53,18 +51,6 @@ export default function TransactionsCard({ openTransfer, openHistory, openTopUp
Historique
-
-
- }
- aria-label="Recharger"
- onClick={openTopUp}
- color="inherit"
- >
- Recharger
-
-
);
diff --git a/app/components/hub/transactions/operations/topUp/TopUp.tsx b/app/components/hub/transactions/operations/topUp/TopUp.tsx
deleted file mode 100644
index a17a7ddb..00000000
--- a/app/components/hub/transactions/operations/topUp/TopUp.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { useState } from 'react';
-
-import { useAuthenticatedSession } from '@blitzjs/auth';
-import { useMutation } from '@blitzjs/rpc';
-
-import { TopUpInputType } from 'app/components/forms/validations';
-import Snackbar from 'app/core/layouts/Snackbar';
-import useSnackbar from 'app/entities/hooks/useSnackbar';
-import requestTopUp, { PaymentMethod } from 'app/entities/transactions/mutations/requestTopUp';
-
-import TopUpForm from './TopUpForm';
-
-export default function TopUp() {
- const { open, message, severity, onClose, onShow } = useSnackbar();
- const [paymentMethod, setPaymentMethod] = useState('credit');
- const [topUp] = useMutation(requestTopUp);
-
- const beforeSubmit = (paymentMethod: PaymentMethod) => () => setPaymentMethod(paymentMethod);
-
- const onSuccess = (data: TopUpInputType) => {
- topUp({
- amount: data.amount,
- method: paymentMethod
- }).then(
- (url) => {
- window.location.assign(url as string);
- },
- (error) => {
- onShow('error', error.message);
- }
- );
- };
-
- return (
- <>
-
-
-
- >
- );
-}
diff --git a/app/components/hub/transactions/operations/topUp/TopUpDialog.tsx b/app/components/hub/transactions/operations/topUp/TopUpDialog.tsx
deleted file mode 100644
index 40b83809..00000000
--- a/app/components/hub/transactions/operations/topUp/TopUpDialog.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import Dialog from '@mui/material/Dialog';
-import DialogActions from '@mui/material/DialogActions';
-import DialogContent from '@mui/material/DialogContent';
-import IconButton from '@mui/material/IconButton';
-import NoSsr from '@mui/material/NoSsr';
-
-import Close from '@mui/icons-material/CloseTwoTone';
-
-import TopUp from 'app/components/hub/transactions/operations/topUp/TopUp';
-import SlideTransition from 'app/core/layouts/SlideTransition';
-import { useMediaQuery } from 'app/core/styles/theme';
-
-type TopUpDialogProps = {
- isOpen: boolean;
- onClose: () => void;
-};
-
-export default function TopUpDialog({ isOpen, onClose }: TopUpDialogProps) {
- const fullScreen = useMediaQuery('md');
-
- return (
-
-
-
- );
-}
diff --git a/app/components/hub/transactions/operations/topUp/TopUpForm.tsx b/app/components/hub/transactions/operations/topUp/TopUpForm.tsx
deleted file mode 100644
index f3a5a3e6..00000000
--- a/app/components/hub/transactions/operations/topUp/TopUpForm.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-import Button from '@mui/material/Button';
-import Typography from '@mui/material/Typography';
-
-import Image from 'next/image';
-
-import EnhancedTextField from 'app/components/forms/EnhancedTextfield';
-import { FORM_ERROR, Form } from 'app/components/forms/Form';
-import { TopUpInput, TopUpInputType } from 'app/components/forms/validations';
-import { PaymentMethod } from 'app/entities/transactions/mutations/requestTopUp';
-
-type TopUpFormProps = {
- onSuccess: (values: TopUpInputType) => void;
- beforeSubmit: (paymentMethod: PaymentMethod) => () => void;
-};
-
-export default function TopUpForm(props: TopUpFormProps) {
- const onSubmit = async (values) => {
- try {
- await props.onSuccess(values);
- } catch (error) {
- return {
- [FORM_ERROR]: 'Sorry, we had an unexpected error. Please try again. - ' + error.toString()
- };
- }
- };
-
- return (
-
- );
-}
diff --git a/app/components/public/Clubs.tsx b/app/components/public/Clubs.tsx
index 7ebe9c8b..0ca0229b 100644
--- a/app/components/public/Clubs.tsx
+++ b/app/components/public/Clubs.tsx
@@ -9,7 +9,7 @@ import { Club } from 'db';
import Image from 'next/image';
-import getClubs from 'app/entities/clubs/queries/getClubs';
+import getPublicClubs from 'app/entities/clubs/queries/getPublicClubs';
import Carousel from './carousel';
@@ -46,7 +46,7 @@ export default function Clubs() {
}>
- getQuery={getClubs} queryKey="clubs" />
+ getQuery={getPublicClubs} queryKey="clubs" />
);
diff --git a/app/components/public/Partners.tsx b/app/components/public/Partners.tsx
index 6f465686..39ad48d9 100644
--- a/app/components/public/Partners.tsx
+++ b/app/components/public/Partners.tsx
@@ -10,7 +10,7 @@ import { Partner } from 'db';
import Image from 'next/image';
import Link from 'app/core/lib/Link';
-import getPartners from 'app/entities/partners/queries/getPartners';
+import getPublicPartners from 'app/entities/partners/queries/getPublicPartners';
import Carousel from './carousel';
@@ -52,7 +52,7 @@ export default function Partners() {
}>
- getQuery={getPartners} queryKey="partners" />
+ getQuery={getPublicPartners} queryKey="partners" />
);
diff --git a/app/core/utils/topup.ts b/app/core/utils/topup.ts
deleted file mode 100644
index 3ed675fb..00000000
--- a/app/core/utils/topup.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import { BinaryLike, KeyObject, createHmac } from 'crypto';
-
-export function makeMerchantReference(card: number, timestamp: number) {
- const card_prefix = card > 0 ? 'p' : 'm';
-
- return `r${card_prefix}${Math.abs(card)}t${Math.ceil(timestamp)}`;
-}
-
-export function makeShopOrderReference(card: number, amount: number) {
- const card_prefix = card > 0 ? 'p' : 'm';
-
- return `o${card_prefix}${Math.abs(card)}a${amount}`;
-}
-
-export function makeHmac(elements: any[], secret: BinaryLike | KeyObject) {
- return createHmac('sha1', secret).update(elements.join('*')).digest('hex');
-}
-
-export type TopUpInfo = {
- userId: string;
- card: number;
- amount: number;
- reference: string;
- orderReference: string;
- creationDate: number;
- byCreditCard: boolean;
-};
-
-export function generateTopUpToken(info: TopUpInfo, secret: BinaryLike | KeyObject) {
- let ret = Buffer.from(JSON.stringify(info)).toString('base64url');
-
- return `${ret}.${createHmac('sha256', secret).update(ret).digest('hex')}`;
-}
-
-export function parseTopUpToken(token: string, secret: BinaryLike | KeyObject) {
- let data = token.split('.');
-
- if (data.length != 2) return null;
-
- if (data[1] != createHmac('sha256', secret).update(data[0]).digest('hex')) return null;
-
- try {
- return JSON.parse(Buffer.from(data[0], 'base64url').toString('utf8'));
- } catch {
- return null;
- }
-}
diff --git a/app/entities/clubs/queries/getClubs.ts b/app/entities/clubs/queries/getClubs.ts
index ee201e8f..287e8a7a 100644
--- a/app/entities/clubs/queries/getClubs.ts
+++ b/app/entities/clubs/queries/getClubs.ts
@@ -4,40 +4,25 @@ import { resolver } from '@blitzjs/rpc';
type GetClubsInput = Pick;
-export default resolver.pipe(async ({ where, orderBy, skip = 0, take }: GetClubsInput, ctx) => {
- console.log(ctx.session.roles);
-
- if (ctx.session.roles?.includes('*') != true && ctx.session.role?.includes('bde') != true) {
- const limit: Prisma.ClubWhereInput = {
- NOT: {
- OR: [{ name: 'listeux' }, { name: 'troll' }]
- }
+export default resolver.pipe(
+ resolver.authorize(['*', 'bde']),
+ async ({ where, orderBy, skip = 0, take }: GetClubsInput, _ctx) => {
+ const clubs = await db.club.findMany({
+ where,
+ orderBy,
+ take,
+ skip
+ });
+
+ const count = await db.club.count({ where });
+ const hasMore = typeof take === 'number' ? skip + take < count : false;
+ const nextPage = hasMore ? { take, skip: skip + take! } : null;
+
+ return {
+ clubs,
+ nextPage,
+ hasMore,
+ count
};
-
- if (where) {
- where = {
- AND: [where, limit]
- };
- } else {
- where = limit;
- }
}
-
- const clubs = await db.club.findMany({
- where,
- orderBy,
- take,
- skip
- });
-
- const count = await db.club.count({ where });
- const hasMore = typeof take === 'number' ? skip + take < count : false;
- const nextPage = hasMore ? { take, skip: skip + take! } : null;
-
- return {
- clubs,
- nextPage,
- hasMore,
- count
- };
-});
+);
diff --git a/app/entities/clubs/queries/getPublicClubs.ts b/app/entities/clubs/queries/getPublicClubs.ts
new file mode 100644
index 00000000..ebb24ed9
--- /dev/null
+++ b/app/entities/clubs/queries/getPublicClubs.ts
@@ -0,0 +1,23 @@
+import db from 'db';
+
+import { resolver } from '@blitzjs/rpc';
+
+type GetPublicClubsInput = {};
+
+export default resolver.pipe(async ({}: GetPublicClubsInput, _ctx) => {
+ const clubs = await db.club.findMany({
+ where: {
+ name: {
+ notIn: ['*', 'listeux']
+ },
+ isPublic: true
+ },
+ orderBy: {
+ name: 'asc'
+ }
+ });
+
+ return {
+ clubs
+ };
+});
diff --git a/app/entities/partners/queries/getPartners.ts b/app/entities/partners/queries/getPartners.ts
index d1010d86..1923d2f6 100644
--- a/app/entities/partners/queries/getPartners.ts
+++ b/app/entities/partners/queries/getPartners.ts
@@ -4,22 +4,25 @@ import { resolver } from '@blitzjs/rpc';
type GetPartnersInput = Pick;
-export default resolver.pipe(async ({ where, orderBy, skip = 0, take }: GetPartnersInput) => {
- const partners = await db.partner.findMany({
- where,
- orderBy,
- take,
- skip
- });
+export default resolver.pipe(
+ resolver.authorize(['*', 'bde']),
+ async ({ where, orderBy, skip = 0, take }: GetPartnersInput, _ctx) => {
+ const partners = await db.partner.findMany({
+ where,
+ orderBy,
+ take,
+ skip
+ });
- const count = await db.partner.count({ where });
- const hasMore = typeof take === 'number' ? skip + take < count : false;
- const nextPage = hasMore ? { take, skip: skip + take! } : null;
+ const count = await db.partner.count({ where });
+ const hasMore = typeof take === 'number' ? skip + take < count : false;
+ const nextPage = hasMore ? { take, skip: skip + take! } : null;
- return {
- partners,
- nextPage,
- hasMore,
- count
- };
-});
+ return {
+ partners,
+ nextPage,
+ hasMore,
+ count
+ };
+ }
+);
diff --git a/app/entities/partners/queries/getPublicPartners.ts b/app/entities/partners/queries/getPublicPartners.ts
new file mode 100644
index 00000000..2382f809
--- /dev/null
+++ b/app/entities/partners/queries/getPublicPartners.ts
@@ -0,0 +1,20 @@
+import db, { Prisma } from 'db';
+
+import { resolver } from '@blitzjs/rpc';
+
+type GetPublicPartnersInput = {};
+
+export default resolver.pipe(async ({}: GetPublicPartnersInput) => {
+ const partners = await db.partner.findMany({
+ where: {
+ isPublic: true
+ },
+ orderBy: {
+ name: 'asc'
+ }
+ });
+
+ return {
+ partners
+ };
+});
diff --git a/app/entities/transactions/mutations/requestTopUp.ts b/app/entities/transactions/mutations/requestTopUp.ts
deleted file mode 100644
index 05f3c4d1..00000000
--- a/app/entities/transactions/mutations/requestTopUp.ts
+++ /dev/null
@@ -1,131 +0,0 @@
-import { Ctx } from 'blitz';
-
-import { resolver } from '@blitzjs/rpc';
-
-import { generateTopUpToken, makeHmac, makeMerchantReference, makeShopOrderReference } from 'app/core/utils/topup';
-
-type RequestTopUpInput = {
- amount: number;
- method: PaymentMethod;
-};
-
-export type PaymentMethod = 'credit' | 'lyf';
-
-function generateHmac(data: URLSearchParams, additionalData: string, byCreditCard: boolean): string {
- let list = [data.get('lang')];
-
- let common = [
- data.get('posUuid'),
- data.get('shopReference'),
- data.get('shopOrderReference'),
- data.get('deliveryFeesAmount'),
- data.get('amount'),
- data.get('currency')
- ];
-
- if (byCreditCard) {
- list = list.concat(common);
- list = list.concat([
- data.get('onSuccess'),
- data.get('onError'),
- additionalData,
- data.get('callBackRequired'),
- data.get('mode'),
- data.get('address'),
- data.get('city'),
- data.get('country'),
- data.get('zipCode')
- ]);
- } else {
- list = list.concat([data.get('version'), data.get('timestamp')]);
- list = list.concat(common);
- list = list.concat([
- data.get('mode'),
- data.get('onSuccess'),
- data.get('onCancel'),
- data.get('onError'),
- additionalData,
- data.get('enforcedIdentification')
- ]);
- }
-
- return makeHmac(list, `${process.env.LYF_API_SECRET_KEY}`);
-}
-
-function prepareRequest(id: string, card: number, amount: number, byCreditCard: boolean): URLSearchParams {
- const body = new URLSearchParams();
-
- const timestamp = Math.floor(+new Date() / 1000);
- const tAmount = Math.round(amount * 100);
-
- const shopReference = makeMerchantReference(card, timestamp);
- const shopOrderReference = makeShopOrderReference(card, tAmount);
-
- const token = generateTopUpToken(
- {
- userId: id,
- card,
- amount: tAmount,
- reference: shopReference,
- orderReference: shopOrderReference,
- creationDate: timestamp,
- byCreditCard
- },
- `${process.env.SESSION_SECRET_KEY}`
- );
-
- const userCallbackUrl = `${process.env.NEXT_PUBLIC_FRONTEND_URL}/hub`;
- const additionalData = `{"callbackUrl":"${process.env.NEXT_PUBLIC_FRONTEND_URL}/api/topup/${token}"}`;
-
- // Common request fields
- body.append('lang', 'fr');
- body.append('version', 'v2.0');
- body.append('posUuid', `${process.env.LYF_API_VENDOR_ID}`);
- body.append('shopReference', shopReference);
- body.append('shopOrderReference', shopOrderReference);
- body.append('mode', 'IMMEDIATE');
- body.append('amount', `${tAmount}`);
- body.append('deliveryFeesAmount', '0');
- body.append('currency', 'EUR');
- body.append('onSuccess', userCallbackUrl);
- body.append('onError', userCallbackUrl);
- body.append('additionalDataEncoded', Buffer.from(additionalData).toString('base64'));
-
- // Method-specific fields
- if (byCreditCard) {
- body.append('caseNumber', '01234');
- body.append('callBackRequired', 'true');
- body.append('country', 'FR');
-
- if (process.env.NODE_ENV === 'development') {
- body.append('address', '7 Some Street');
- body.append('city', 'Bigcity');
- body.append('zipCode', '01234');
- } else {
- body.append('address', '');
- body.append('city', '');
- body.append('zipCode', '');
- }
- } else {
- body.append('onCancel', userCallbackUrl);
- body.append('timestamp', `${timestamp}`);
- body.append('enforcedIdentification', 'false');
- }
-
- body.append('mac', generateHmac(body, additionalData, byCreditCard));
-
- return body;
-}
-
-export default resolver.pipe(resolver.authorize(), async (input: RequestTopUpInput, ctx: Ctx) => {
- if (Number.isNaN(input.amount) || input.amount <= 0 || input.amount >= 1000) {
- throw new Error('Valeur invalide');
- }
-
- const byCreditCard = input.method == 'credit';
- const req = prepareRequest(ctx.session.userId as string, ctx.session.card as number, input.amount, byCreditCard);
-
- return `${
- byCreditCard ? process.env.LYF_CREDIT_CARD_API_URL : process.env.LYF_FROM_APPLICATION_API_URL
- }?${req.toString()}`;
-});
diff --git a/db/schema.prisma b/db/schema.prisma
index 99e64b53..09daf707 100644
--- a/db/schema.prisma
+++ b/db/schema.prisma
@@ -115,6 +115,8 @@ model Club {
instagramURL String?
customURL String?
+ isPublic Boolean @default(true)
+
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
Event Event[] @relation("EventClub")
@@ -127,6 +129,8 @@ model Partner {
description String?
image String?
+ isPublic Boolean @default(true)
+
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
diff --git a/db/seeds/users.ts b/db/seeds/users.ts
index 824ddab1..a107bb61 100644
--- a/db/seeds/users.ts
+++ b/db/seeds/users.ts
@@ -26,7 +26,7 @@ const users = async (db) => {
firstname: 'Venceslas',
nickname: 'venny',
image: 'https://i.imgur.com/VbdBkxz.png',
- email: 'duet.venceslas@orange.fr',
+ email: 'contact@citorva.fr',
card: 1463,
balance: 0,
roles: '*',
diff --git a/package.json b/package.json
index 287a19ee..c2fe3cc8 100644
--- a/package.json
+++ b/package.json
@@ -50,6 +50,7 @@
"@mui/x-date-pickers": "^5.0.13",
"@prisma/client": "^4.8.1",
"blitz": "2.0.0-beta.21",
+ "caniuse-lite": "^1.0.30001553",
"chart.js": "3.9.1",
"cuid": "^2.1.8",
"date-fns": "^2.29.3",
diff --git a/pages/api/topup/[token].ts b/pages/api/topup/[token].ts
deleted file mode 100644
index 25fb0245..00000000
--- a/pages/api/topup/[token].ts
+++ /dev/null
@@ -1,107 +0,0 @@
-import db from 'db';
-import { NextApiRequest, NextApiResponse } from 'next';
-
-import { makeHmac, makeMerchantReference, makeShopOrderReference, parseTopUpToken } from 'app/core/utils/topup';
-
-export default async function handler(req: NextApiRequest, res: NextApiResponse) {
- if (req.method === 'POST') {
- const { body, query } = req;
-
- const token = query.token as string;
-
- const tokenInfo = parseTopUpToken(token, `${process.env.SESSION_SECRET_KEY}`);
-
- if (tokenInfo == null) {
- res.status(404).send('BAD TOKEN');
- return;
- }
-
- // Data retrieval
-
- const {
- posUuid,
- shopReference,
- shopOrderReference,
- amount,
- discount,
- currency,
- status,
- creationDate,
- transactionUuid,
- additionalData,
- mac
- } = body;
-
- // Verification of data authenticity
-
- const testMAC = makeHmac(
- [
- posUuid,
- shopReference,
- shopOrderReference,
- amount,
- discount,
- currency,
- status,
- creationDate,
- transactionUuid,
- additionalData
- ],
- `${process.env.LYF_API_SECRET_KEY}`
- ).toUpperCase();
-
- if (testMAC != mac) {
- res.status(400).send('BAD MAC');
- return;
- }
-
- // Verification of data consistency
-
- if (
- posUuid != `${process.env.LYF_API_VENDOR_ID}` ||
- shopReference != makeMerchantReference(tokenInfo.card, tokenInfo.creationDate) ||
- shopOrderReference != makeShopOrderReference(tokenInfo.card, tokenInfo.amount) ||
- amount != tokenInfo.amount ||
- currency != 'EUR' ||
- ['VALIDATED', 'REFUSED'].indexOf(status) <= -1
- ) {
- res.status(400).send('INCONSISTENT DATA');
- return;
- }
-
- // Checking the status of the request
-
- if (status == 'VALIDATED') {
- // Adding money to the user
-
- const user = await db.user.findUnique({ where: { id: tokenInfo.userId } });
-
- if (user != null) {
- const qAmount = amount / 100;
-
- await Promise.all([
- db.transaction.create({
- data: {
- amount: qAmount,
- description: `Rechargement +${qAmount}€`,
- type: 'CREDIT',
- user: { connect: { id: tokenInfo.userId } },
- prevBalance: user.balance
- }
- }),
- db.user.update({
- where: { id: tokenInfo.userId },
- data: { balance: { increment: qAmount } }
- })
- ]);
- res.status(200).send('OK');
- } else {
- res.status(500).send('UNKNOWN USER');
- }
- } else {
- res.status(200).send('OK');
- }
- } else {
- res.status(400).send('BAD REQUEST');
- }
-}
diff --git a/pages/dashboard/clubs.tsx b/pages/dashboard/clubs.tsx
index 0bfeb705..810b2f22 100644
--- a/pages/dashboard/clubs.tsx
+++ b/pages/dashboard/clubs.tsx
@@ -1,3 +1,4 @@
+import { Checkbox } from '@mui/material';
import Avatar from '@mui/material/Avatar';
import GroupsIcon from '@mui/icons-material/Groups';
@@ -56,6 +57,11 @@ const columns = [
id: 'email',
headerName: 'Email',
searchCriteria: 'contains'
+ },
+ {
+ id: 'isPublic',
+ headerName: 'Public',
+ render: (row) =>
}
];
diff --git a/pages/dashboard/partners.tsx b/pages/dashboard/partners.tsx
index 0f2fee50..5d345a6a 100644
--- a/pages/dashboard/partners.tsx
+++ b/pages/dashboard/partners.tsx
@@ -1,3 +1,4 @@
+import { Checkbox } from '@mui/material';
import Avatar from '@mui/material/Avatar';
import AccountBalance from '@mui/icons-material/AccountBalance';
@@ -55,6 +56,11 @@ const columns = [
id: 'description',
headerName: 'Description',
searchCriteria: 'contains'
+ },
+ {
+ id: 'isPublic',
+ headerName: 'Public',
+ render: (row) =>
}
];
diff --git a/pages/hub/index.tsx b/pages/hub/index.tsx
index 32b9a06a..5f11bc07 100644
--- a/pages/hub/index.tsx
+++ b/pages/hub/index.tsx
@@ -1,5 +1,7 @@
import { useState } from 'react';
+import { Alert } from '@mui/material';
+
import { BlitzPage, Routes } from '@blitzjs/next';
import Upcoming from 'app/components/hub/events/Upcoming';
@@ -7,14 +9,12 @@ import DiscordButton from 'app/components/hub/home/DiscordButton';
import News from 'app/components/hub/home/News';
import TransactionsCard from 'app/components/hub/transactions/display/TransactionsCard';
import HistoryDialog from 'app/components/hub/transactions/operations/history/HistoryDialog';
-import TopUpDialog from 'app/components/hub/transactions/operations/topUp/TopUpDialog';
import TransferDialog from 'app/components/hub/transactions/operations/transfer/TransferDialog';
import getHubNav from 'app/components/nav/hub/getHubNav';
const Hub: BlitzPage = () => {
const [isTransferOpen, setIsTransferOpen] = useState(false);
const [isHistoryOpen, setIsHistoryOpen] = useState(false);
- const [isTopUpOpen, setIsTopUpOpen] = useState(false);
const toggleDialog = (fn, open) => () => fn(open);
@@ -24,6 +24,10 @@ const Hub: BlitzPage = () => {
style={{ gridTemplateColumns: '1fr 310px' }}
>
+
+ Suite à des problèmes techniques, le rechargement en ligne a été temporairement désactivé. Veuillez
+ vous rapprocher d'un membre du BDE afin de recharger votre compte
+
@@ -32,12 +36,10 @@ const Hub: BlitzPage = () => {
-
);
diff --git a/yarn.lock b/yarn.lock
index aa68810f..7c65fd0e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3013,9 +3013,14 @@ camelcase@^7.0.0:
integrity sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==
caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001406, caniuse-lite@^1.0.30001426:
- version "1.0.30001442"
- resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001442.tgz"
- integrity sha512-239m03Pqy0hwxYPYR5JwOIxRJfLTWtle9FV8zosfV5pHg+/51uD4nxcUlM8+mWWGfwKtt8lJNHnD3cWw9VZ6ow==
+ version "1.0.30001553"
+ resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001553.tgz"
+ integrity sha512-N0ttd6TrFfuqKNi+pMgWJTb9qrdJu4JSpgPFLe/lrD19ugC6fZgF0pUewRowDwzdDnb9V41mFcdlYgl/PyKf4A==
+
+caniuse-lite@^1.0.30001553:
+ version "1.0.30001672"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001672.tgz#02ac296ad4765c6c4f93031525f60cf8bdf4a44f"
+ integrity sha512-XhW1vRo1ob6aeK2w3rTohwTPBLse/rvjq+s3RTSBwnlZqoFFjx9cHsShJjAIbLsLjyoacaTxpLZy9v3gg6zypw==
chalk@^2.0.0:
version "2.4.2"