Compare commits

...

7 Commits

Author SHA1 Message Date
Ahmed Bouhuolia
82dc228cfe feat: wip attachments 2024-05-17 12:25:42 +02:00
Ahmed Bouhuolia
4f30f72d36 chore: remove the unused hook 2024-05-15 14:03:34 +02:00
Ahmed Bouhuolia
3f68d11062 fix: Showing the real mail address on email confirmation view 2024-05-15 14:01:22 +02:00
allcontributors[bot]
370a8a4b91 docs: add ccantrell72 as a contributor for bug (#441)
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2024-05-13 08:42:27 +02:00
Chris Cantrell
c9ba9500cc fix: typo in setup wizard (#440)
Fixed spelling error
2024-05-13 08:39:51 +02:00
Ahmed Bouhuolia
23d27cafc1 fix: Update Dockerfile 2024-05-10 11:36:01 +02:00
Ahmed Bouhuolia
92e3d31360 fix: use server container from Docker registry instead 2024-05-09 20:10:49 +02:00
18 changed files with 1329 additions and 41 deletions

View File

@@ -123,6 +123,15 @@
"contributions": [
"code"
]
},
{
"login": "ccantrell72",
"name": "Chris Cantrell",
"avatar_url": "https://avatars.githubusercontent.com/u/104120598?v=4",
"profile": "http://www.pivoten.com",
"contributions": [
"bug"
]
}
],
"contributorsPerLine": 7,

View File

@@ -124,6 +124,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<td align="center" valign="top" width="14.28%"><a href="https://github.com/asenawritescode"><img src="https://avatars.githubusercontent.com/u/67445192?v=4?s=100" width="100px;" alt="Asena"/><br /><sub><b>Asena</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/issues?q=author%3Aasenawritescode" title="Bug reports">🐛</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://snyder.tech"><img src="https://avatars.githubusercontent.com/u/707567?v=4?s=100" width="100px;" alt="Ben Snyder"/><br /><sub><b>Ben Snyder</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/commits?author=benpsnyder" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://vederis.id"><img src="https://avatars.githubusercontent.com/u/13505006?v=4?s=100" width="100px;" alt="Vederis Leunardus"/><br /><sub><b>Vederis Leunardus</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/commits?author=cloudsbird" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.pivoten.com"><img src="https://avatars.githubusercontent.com/u/104120598?v=4?s=100" width="100px;" alt="Chris Cantrell"/><br /><sub><b>Chris Cantrell</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/issues?q=author%3Accantrell72" title="Bug reports">🐛</a></td>
</tr>
</tbody>
</table>

View File

@@ -1,4 +1,4 @@
FROM ghcr.io/bigcapitalhq/server:latest as build
FROM bigcapitalhq/server:latest as build
ARG DB_HOST= \
DB_USER= \
@@ -34,8 +34,5 @@ WORKDIR /app/packages/server
RUN git clone https://github.com/vishnubob/wait-for-it.git
ADD docker/migration/start.sh /
RUN chmod +x /start.sh
# Once we listen the mysql port run the migration task.
CMD ./wait-for-it/wait-for-it.sh mysql:3306 -- sh -c "node ./build/commands.js system:migrate:latest && node ./build/commands.js tenants:migrate:latest"

View File

@@ -0,0 +1,24 @@
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":4846,"time":"2024-05-15T09:09:09.492Z","msg":"Unable to find configuration file. If a configuration file is desired (common for non-containerized environments), a base configuration file can be copied from /Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/newrelic.js and renamed to \"newrelic.js\" in the directory from which you will start your application. Attempting to start agent using environment variables."}
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":4846,"time":"2024-05-15T09:09:09.514Z","msg":"Using New Relic for Node.js. Agent version: 11.16.0; Node version: v18.18.2."}
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":4846,"time":"2024-05-15T09:09:09.791Z","msg":"Using AsyncLocalContextManager"}
{"v":0,"level":50,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":4846,"time":"2024-05-15T09:09:09.793Z","msg":"New Relic for Node.js was unable to bootstrap itself due to an error:","stack":"Error: New Relic requires that you name this application!\nSet app_name in your newrelic.js or newrelic.cjs file or set environment variable\nNEW_RELIC_APP_NAME. Not starting!\n at createAgent (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/index.js:160:11)\n at initialize (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/index.js:105:15)\n at Object.<anonymous> (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/index.js:39:3)\n at Module._compile (node:internal/modules/cjs/loader:1256:14)\n at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)\n at Module.load (node:internal/modules/cjs/loader:1119:32)\n at Module._load (node:internal/modules/cjs/loader:960:12)\n at Module.require (node:internal/modules/cjs/loader:1143:19)\n at require (node:internal/modules/cjs/helpers:119:18)\n at Object.newrelic (/Users/ahmedbouhuolia/repos/bigcapital/packages/server/build/index.js:15954:18)","message":"New Relic requires that you name this application!\nSet app_name in your newrelic.js or newrelic.cjs file or set environment variable\nNEW_RELIC_APP_NAME. Not starting!"}
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":4883,"time":"2024-05-15T09:09:27.758Z","msg":"Unable to find configuration file. If a configuration file is desired (common for non-containerized environments), a base configuration file can be copied from /Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/newrelic.js and renamed to \"newrelic.js\" in the directory from which you will start your application. Attempting to start agent using environment variables."}
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":4883,"time":"2024-05-15T09:09:27.771Z","msg":"Using New Relic for Node.js. Agent version: 11.16.0; Node version: v18.18.2."}
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":4883,"time":"2024-05-15T09:09:27.927Z","msg":"Using AsyncLocalContextManager"}
{"v":0,"level":50,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":4883,"time":"2024-05-15T09:09:27.929Z","msg":"New Relic for Node.js was unable to bootstrap itself due to an error:","stack":"Error: New Relic requires that you name this application!\nSet app_name in your newrelic.js or newrelic.cjs file or set environment variable\nNEW_RELIC_APP_NAME. Not starting!\n at createAgent (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/index.js:160:11)\n at initialize (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/index.js:105:15)\n at Object.<anonymous> (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/index.js:39:3)\n at Module._compile (node:internal/modules/cjs/loader:1256:14)\n at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)\n at Module.load (node:internal/modules/cjs/loader:1119:32)\n at Module._load (node:internal/modules/cjs/loader:960:12)\n at Module.require (node:internal/modules/cjs/loader:1143:19)\n at require (node:internal/modules/cjs/helpers:119:18)\n at Object.newrelic (/Users/ahmedbouhuolia/repos/bigcapital/packages/server/build/index.js:15954:18)","message":"New Relic requires that you name this application!\nSet app_name in your newrelic.js or newrelic.cjs file or set environment variable\nNEW_RELIC_APP_NAME. Not starting!"}
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":5411,"time":"2024-05-15T09:15:10.318Z","msg":"Unable to find configuration file. If a configuration file is desired (common for non-containerized environments), a base configuration file can be copied from /Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/newrelic.js and renamed to \"newrelic.js\" in the directory from which you will start your application. Attempting to start agent using environment variables."}
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":5411,"time":"2024-05-15T09:15:10.326Z","msg":"Using New Relic for Node.js. Agent version: 11.16.0; Node version: v18.18.2."}
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":5411,"time":"2024-05-15T09:15:10.420Z","msg":"Using AsyncLocalContextManager"}
{"v":0,"level":50,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":5411,"time":"2024-05-15T09:15:10.421Z","msg":"New Relic for Node.js was unable to bootstrap itself due to an error:","stack":"Error: New Relic requires that you name this application!\nSet app_name in your newrelic.js or newrelic.cjs file or set environment variable\nNEW_RELIC_APP_NAME. Not starting!\n at createAgent (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/index.js:160:11)\n at initialize (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/index.js:105:15)\n at Object.<anonymous> (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/index.js:39:3)\n at Module._compile (node:internal/modules/cjs/loader:1256:14)\n at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)\n at Module.load (node:internal/modules/cjs/loader:1119:32)\n at Module._load (node:internal/modules/cjs/loader:960:12)\n at Module.require (node:internal/modules/cjs/loader:1143:19)\n at require (node:internal/modules/cjs/helpers:119:18)\n at Object.newrelic (/Users/ahmedbouhuolia/repos/bigcapital/packages/server/build/index.js:15954:18)","message":"New Relic requires that you name this application!\nSet app_name in your newrelic.js or newrelic.cjs file or set environment variable\nNEW_RELIC_APP_NAME. Not starting!"}
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":8856,"time":"2024-05-15T11:47:03.324Z","msg":"Unable to find configuration file. If a configuration file is desired (common for non-containerized environments), a base configuration file can be copied from /Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/newrelic.js and renamed to \"newrelic.js\" in the directory from which you will start your application. Attempting to start agent using environment variables."}
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":8856,"time":"2024-05-15T11:47:03.335Z","msg":"Using New Relic for Node.js. Agent version: 11.16.0; Node version: v18.18.2."}
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":8856,"time":"2024-05-15T11:47:03.504Z","msg":"Using AsyncLocalContextManager"}
{"v":0,"level":50,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":8856,"time":"2024-05-15T11:47:03.505Z","msg":"New Relic for Node.js was unable to bootstrap itself due to an error:","stack":"Error: New Relic requires that you name this application!\nSet app_name in your newrelic.js or newrelic.cjs file or set environment variable\nNEW_RELIC_APP_NAME. Not starting!\n at createAgent (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/index.js:160:11)\n at initialize (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/index.js:105:15)\n at Object.<anonymous> (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/index.js:39:3)\n at Module._compile (node:internal/modules/cjs/loader:1256:14)\n at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)\n at Module.load (node:internal/modules/cjs/loader:1119:32)\n at Module._load (node:internal/modules/cjs/loader:960:12)\n at Module.require (node:internal/modules/cjs/loader:1143:19)\n at require (node:internal/modules/cjs/helpers:119:18)\n at Object.newrelic (/Users/ahmedbouhuolia/repos/bigcapital/packages/server/build/index.js:15954:18)","message":"New Relic requires that you name this application!\nSet app_name in your newrelic.js or newrelic.cjs file or set environment variable\nNEW_RELIC_APP_NAME. Not starting!"}
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":12076,"time":"2024-05-15T14:30:36.984Z","msg":"Unable to find configuration file. If a configuration file is desired (common for non-containerized environments), a base configuration file can be copied from /Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/newrelic.js and renamed to \"newrelic.js\" in the directory from which you will start your application. Attempting to start agent using environment variables."}
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":12076,"time":"2024-05-15T14:30:36.990Z","msg":"Using New Relic for Node.js. Agent version: 11.16.0; Node version: v18.18.2."}
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":12076,"time":"2024-05-15T14:30:37.126Z","msg":"Using AsyncLocalContextManager"}
{"v":0,"level":50,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":12076,"time":"2024-05-15T14:30:37.127Z","msg":"New Relic for Node.js was unable to bootstrap itself due to an error:","stack":"Error: New Relic requires that you name this application!\nSet app_name in your newrelic.js or newrelic.cjs file or set environment variable\nNEW_RELIC_APP_NAME. Not starting!\n at createAgent (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/index.js:160:11)\n at initialize (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/index.js:105:15)\n at Object.<anonymous> (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/index.js:39:3)\n at Module._compile (node:internal/modules/cjs/loader:1256:14)\n at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)\n at Module.load (node:internal/modules/cjs/loader:1119:32)\n at Module._load (node:internal/modules/cjs/loader:960:12)\n at Module.require (node:internal/modules/cjs/loader:1143:19)\n at require (node:internal/modules/cjs/helpers:119:18)\n at Object.newrelic (/Users/ahmedbouhuolia/repos/bigcapital/packages/server/build/index.js:15954:18)","message":"New Relic requires that you name this application!\nSet app_name in your newrelic.js or newrelic.cjs file or set environment variable\nNEW_RELIC_APP_NAME. Not starting!"}
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":29079,"time":"2024-05-17T10:24:22.393Z","msg":"Unable to find configuration file. If a configuration file is desired (common for non-containerized environments), a base configuration file can be copied from /Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/newrelic.js and renamed to \"newrelic.js\" in the directory from which you will start your application. Attempting to start agent using environment variables."}
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":29079,"time":"2024-05-17T10:24:22.405Z","msg":"Using New Relic for Node.js. Agent version: 11.16.0; Node version: v18.18.2."}
{"v":0,"level":30,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":29079,"time":"2024-05-17T10:24:22.536Z","msg":"Using AsyncLocalContextManager"}
{"v":0,"level":50,"name":"newrelic","hostname":"Ahmeds-MacBook-Air.local","pid":29079,"time":"2024-05-17T10:24:22.537Z","msg":"New Relic for Node.js was unable to bootstrap itself due to an error:","stack":"Error: New Relic requires that you name this application!\nSet app_name in your newrelic.js or newrelic.cjs file or set environment variable\nNEW_RELIC_APP_NAME. Not starting!\n at createAgent (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/index.js:160:11)\n at initialize (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/index.js:105:15)\n at Object.<anonymous> (/Users/ahmedbouhuolia/repos/bigcapital/node_modules/.pnpm/newrelic@11.16.0/node_modules/newrelic/index.js:39:3)\n at Module._compile (node:internal/modules/cjs/loader:1256:14)\n at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)\n at Module.load (node:internal/modules/cjs/loader:1119:32)\n at Module._load (node:internal/modules/cjs/loader:960:12)\n at Module.require (node:internal/modules/cjs/loader:1143:19)\n at require (node:internal/modules/cjs/helpers:119:18)\n at Object.newrelic (/Users/ahmedbouhuolia/repos/bigcapital/packages/server/build/index.js:15954:18)","message":"New Relic requires that you name this application!\nSet app_name in your newrelic.js or newrelic.cjs file or set environment variable\nNEW_RELIC_APP_NAME. Not starting!"}

View File

@@ -20,6 +20,7 @@
"bigcapital": "./bin/bigcapital.js"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.576.0",
"@casl/ability": "^5.4.3",
"@hapi/boom": "^7.4.3",
"@lemonsqueezy/lemonsqueezy.js": "^2.2.0",

View File

@@ -0,0 +1,35 @@
import { Service, Inject } from 'typedi';
import { Router, Response } from 'express';
import BaseController from '@/api/controllers/BaseController';
import { Request } from 'express-validator/src/base';
import { AttachmentsApplication } from '@/services/Attachments/AttachmentsApplication';
@Service()
export class AttachmentsController extends BaseController {
@Inject()
private attachmentsApplication: AttachmentsApplication;
/**
* Router constructor.
*/
router() {
const router = Router();
router.delete('/:id', this.deleteAttachment.bind(this));
router.post('/', this.uploadAttachment.bind(this));
return router;
}
private async uploadAttachment(req: Request, res: Response, next: Function) {
try {
await this.attachmentsApplication.upload();
return res.status(200).send({});
} catch (error) {
next(error);
}
}
private deleteAttachment(req: Request, res: Response, next: Function) {}
}

View File

@@ -0,0 +1,20 @@
import { Inject, Service } from "typedi";
import { UploadDocument } from "./UploadDocument";
@Service()
export class AttachmentsApplication {
@Inject()
private uploadDocumentService: UploadDocument;
upload(data: any) {
return this.uploadDocumentService.upload(data);
}
delete(attachmentId: string) {}
get(attachmentId: string) {
}
}

View File

@@ -0,0 +1,22 @@
import { Service } from 'typedi';
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
@Service()
export class UploadDocument {
// setting up s3 client
public s3 = new S3Client({
region: process.env.AWS_REGION,
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
});
async upload(data) {
const putObjectCommand = new PutObjectCommand({
Bucket: process.env.AWS_BUCKET,
Key: data.filename,
Body: await data.toBuffer(),
ContentType: data.mimetype,
});
await this.s3.send(putObjectCommand);
}
}

View File

@@ -9,7 +9,11 @@ import AuthInsider from '@/containers/Authentication/AuthInsider';
import { useAuthLogin, useAuthRegister } from '@/hooks/query/authentication';
import RegisterForm from './RegisterForm';
import { RegisterSchema, transformRegisterErrorsToForm, transformRegisterToastMessages } from './utils';
import {
RegisterSchema,
transformRegisterErrorsToForm,
transformRegisterToastMessages,
} from './utils';
import {
AuthFooterLinks,
AuthFooterLink,
@@ -32,7 +36,7 @@ export default function RegisterUserForm() {
const handleSubmit = (values, { setSubmitting, setErrors }) => {
authRegisterMutate(values)
.then((response) => {
.then(() => {
authLoginMutate({
crediential: values.email,
password: values.password,
@@ -87,7 +91,10 @@ function RegisterFooterLinks() {
return (
<AuthFooterLinks>
<AuthFooterLink>
<T id={'return_to'} /> <Link to={'/auth/login'}><T id={'sign_in'} /></Link>
<T id={'return_to'} />{' '}
<Link to={'/auth/login'}>
<T id={'sign_in'} />
</Link>
</AuthFooterLink>
<AuthFooterLink>

View File

@@ -4,7 +4,7 @@ import AuthInsider from './AuthInsider';
import { AuthInsiderCard } from './_components';
import styles from './RegisterVerify.module.scss';
import { AppToaster, Stack } from '@/components';
import { useAuthActions } from '@/hooks/state';
import { useAuthActions, useAuthUserVerifyEmail } from '@/hooks/state';
import { useAuthSignUpVerifyResendMail } from '@/hooks/query';
import { AuthContainer } from './AuthContainer';
@@ -13,6 +13,8 @@ export default function RegisterVerify() {
const { mutateAsync: resendSignUpVerifyMail, isLoading } =
useAuthSignUpVerifyResendMail();
const emailAddress = useAuthUserVerifyEmail();
const handleResendMailBtnClick = () => {
resendSignUpVerifyMail()
.then(() => {
@@ -38,8 +40,8 @@ export default function RegisterVerify() {
<AuthInsiderCard className={styles.root}>
<h2 className={styles.title}>Please verify your email</h2>
<p className={styles.description}>
We sent an email to <strong>asdahmed@gmail.com</strong> Click the
link inside to get started.
We sent an email to <strong>{emailAddress}</strong> Click the link
inside to get started.
</p>
<Stack spacing={4}>

View File

@@ -37,7 +37,7 @@ export default function SetupWizardContent({
<SetupOrganizationPage id="organization" />
</Stepper.Step>
<Stepper.Step label={'Initiializing'}>
<Stepper.Step label={'Initializing'}>
<SetupInitializingForm id={'initializing'} />
</Stepper.Step>

View File

@@ -1,9 +1,17 @@
// @ts-nocheck
import { useMutation } from 'react-query';
import { batch } from 'react-redux';
import useApiRequest from '../useRequest';
import { setCookie } from '../../utils';
import { useRequestQuery } from '../useQueryRequest';
import t from './types';
import {
useSetAuthToken,
useSetAuthUserId,
useSetLocale,
useSetOrganizationId,
useSetTenantId,
} from '../state';
/**
* Saves the response data to cookies.
@@ -24,14 +32,30 @@ function setAuthLoginCookies(data) {
export const useAuthLogin = (props) => {
const apiRequest = useApiRequest();
const setAuthToken = useSetAuthToken();
const setOrganizationId = useSetOrganizationId();
const setUserId = useSetAuthUserId();
const setTenantId = useSetTenantId();
const setLocale = useSetLocale();
return useMutation((values) => apiRequest.post('auth/login', values), {
select: (res) => res.data,
onSuccess: (data) => {
onSuccess: (res) => {
// Set authentication cookies.
setAuthLoginCookies(data.data);
setAuthLoginCookies(res.data);
// Reboot the application.
window.location.reload();
batch(() => {
// Sets the auth metadata to global state.
setAuthToken(res.data.token);
setOrganizationId(res.data.tenant.organization_id);
setUserId(res.data.user.id);
setTenantId(res.data.tenant.id);
if (res.data?.tenant?.metadata?.language) {
setLocale(res.data?.tenant?.metadata?.language);
}
});
props?.onSuccess && props?.onSuccess(...args);
},
...props,
});

View File

@@ -1,7 +1,7 @@
// @ts-nocheck
import { useEffect } from 'react';
import { useMutation, useQueryClient } from 'react-query';
import { useQueryTenant, useRequestQuery } from '../useQueryRequest';
import { useRequestQuery } from '../useQueryRequest';
import useApiRequest from '../useRequest';
import { useSetFeatureDashboardMeta } from '../state/feature';
import t from './types';
@@ -143,7 +143,7 @@ export function useAuthenticatedAccount(props) {
select: (response) => response.data.data,
defaultData: {},
onSuccess: (data) => {
setEmailConfirmed(data.is_verified);
setEmailConfirmed(data.is_verified, data.email);
},
...props,
},

View File

@@ -3,8 +3,13 @@ import { useDispatch, useSelector } from 'react-redux';
import { useCallback } from 'react';
import { isAuthenticated } from '@/store/authentication/authentication.reducer';
import {
setAuthTenantId,
setAuthToken,
setAuthUserId,
setEmailConfirmed,
setLogin,
setOrganizationId,
setLocale,
} from '@/store/authentication/authentication.actions';
import { useQueryClient } from 'react-query';
import { removeCookie } from '@/utils';
@@ -75,6 +80,14 @@ export const useAuthUserVerified = () => {
return useSelector((state) => state.authentication.verified);
};
/**
* Retrieves the user's email address.
* @returns {string}
*/
export const useAuthUserVerifyEmail = () => {
return useSelector((state) => state.authentication.verifyEmail);
};
/**
* Sets the user's email verification status.
*/
@@ -82,7 +95,53 @@ export const useSetAuthEmailConfirmed = () => {
const dispatch = useDispatch();
return useCallback(
(verified?: boolean = true) => dispatch(setEmailConfirmed(verified)),
(verified?: boolean = true, email: string) =>
dispatch(setEmailConfirmed(verified, email)),
[dispatch],
);
};
export const useSetOrganizationId = () => {
const dispatch = useDispatch();
return useCallback(
(organizationId: string) => dispatch(setOrganizationId(organizationId)),
[dispatch],
);
};
export const useSetAuthToken = () => {
const dispatch = useDispatch();
return useCallback(
(authToken: string) => dispatch(setAuthToken(authToken)),
[dispatch],
);
};
export const useSetTenantId = () => {
const dispatch = useDispatch();
return useCallback(
(tenantId: string) => dispatch(setAuthTenantId(tenantId)),
[dispatch],
);
};
export const useSetAuthUserId = () => {
const dispatch = useDispatch();
return useCallback(
(userId: string) => dispatch(setAuthUserId(userId)),
[dispatch],
);
};
export const useSetLocale = () => {
const dispatch = useDispatch();
return useCallback(
(locale: string) => dispatch(setLocale(locale)),
[dispatch],
);
};

View File

@@ -4,7 +4,27 @@ import t from '@/store/types';
export const setLogin = () => ({ type: t.LOGIN_SUCCESS });
export const setLogout = () => ({ type: t.LOGOUT });
export const setStoreReset = () => ({ type: t.RESET });
export const setEmailConfirmed = (verified?: boolean) => ({
export const setEmailConfirmed = (verified?: boolean, email?: string) => ({
type: t.SET_EMAIL_VERIFIED,
action: { verified },
action: { verified, email },
});
export const setOrganizationId = (organizationId: string) => ({
type: t.SET_ORGANIZATIOIN_ID,
action: { organizationId },
});
export const setAuthToken = (token: string) => ({
type: t.SET_AUTH_TOKEN,
action: { token },
});
export const setAuthTenantId = (tenantId: string) => ({
type: t.SET_TENANT_ID,
action: { tenantId },
});
export const setAuthUserId = (userId: string) => ({
type: t.SET_USER_ID,
action: { userId },
});
export const setLocale = (locale: string) => ({
type: t.SET_LOCALE,
action: { locale },
});

View File

@@ -9,12 +9,13 @@ import t from '@/store/types';
// Read stored data in cookies and merge it with the initial state.
const initialState = {
token: getCookie('token'),
organizationId: getCookie('organization_id'),
tenantId: getCookie('tenant_id'),
userId: getCookie('authenticated_user_id'),
locale: getCookie('locale'),
token: getCookie('token') || null,
organizationId: getCookie('organization_id') || null,
tenantId: getCookie('tenant_id') || null,
userId: getCookie('authenticated_user_id') || null,
locale: getCookie('locale') || 'en',
verified: true, // Let's be optimistic and assume the user's email is confirmed.
verifyEmail: null,
errors: [],
};
@@ -36,11 +37,35 @@ const reducerInstance = createReducer(initialState, {
[t.SET_EMAIL_VERIFIED]: (
state,
payload: PayloadAction<{ verified?: boolean }>,
payload: PayloadAction<{ verified?: boolean; email?: string }>,
) => {
state.verified = !isUndefined(payload.action.verified)
? payload.action.verified
: true;
state.verifyEmail = payload.action.email || null;
if (state.verified) {
state.verifyEmail = null;
}
},
[t.SET_AUTH_TOKEN]: (state, payload: PayloadAction<{ token: string }>) => {
state.token = payload.action.token;
},
[t.SET_ORGANIZATIOIN_ID]: (
state,
payload: PayloadAction<{ organizationId: string }>,
) => {
state.organizationId = payload.action.organizationId;
},
[t.SET_TENANT_ID]: (state, payload: PayloadAction<{ tenantId: string }>) => {
state.tenantId = payload.action.tenantId;
},
[t.SET_USER_ID]: (state, payload: PayloadAction<{ userId: string }>) => {
state.userId = payload.action.userId;
},
[t.RESET]: (state) => {

View File

@@ -7,5 +7,10 @@ export default {
LOGOUT: 'LOGOUT',
LOGIN_CLEAR_ERRORS: 'LOGIN_CLEAR_ERRORS',
RESET: 'RESET',
SET_EMAIL_VERIFIED: 'SET_EMAIL_VERIFIED'
SET_EMAIL_VERIFIED: 'SET_EMAIL_VERIFIED',
SET_AUTH_TOKEN: 'SET_AUTH_TOKEN',
SET_ORGANIZATIOIN_ID: 'SET_ORGANIZATIOIN_ID',
SET_TENANT_ID: 'SET_TENANT_ID',
SET_USER_ID: 'SET_USER_ID',
SET_LOCALE: 'SET_LOCALE',
};

1065
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff