Skip to content

Commit

Permalink
Merge branch 'main' into @chrispader/after-revert-bump-onyx-to-2-0-42
Browse files Browse the repository at this point in the history
  • Loading branch information
chrispader committed Jun 12, 2024
2 parents 732e9b5 + 073ce7f commit dfb0b2c
Show file tree
Hide file tree
Showing 138 changed files with 1,860 additions and 659 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ module.exports = {
__DEV__: 'readonly',
},
rules: {
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',

Expand Down Expand Up @@ -167,6 +166,7 @@ module.exports = {

// Rulesdir specific rules
'rulesdir/no-default-props': 'error',
'rulesdir/prefer-type-fest': 'error',
'rulesdir/no-multiple-onyx-in-file': 'off',
'rulesdir/prefer-underscore-method': 'off',
'rulesdir/prefer-import-module-contents': 'off',
Expand Down
13 changes: 11 additions & 2 deletions .github/actions/javascript/getGraphiteString/getGraphiteString.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import * as core from '@actions/core';
import fs from 'fs';

type RegressionEntry = {
metadata?: {
creationDate: string;
};
name: string;
meanDuration: number;
meanCount: number;
};

const run = () => {
// Prefix path to the graphite metric
const GRAPHITE_PATH = 'reassure';
Expand All @@ -24,11 +33,11 @@ const run = () => {
}

try {
const current = JSON.parse(entry);
const current: RegressionEntry = JSON.parse(entry);

// Extract timestamp, Graphite accepts timestamp in seconds
if (current.metadata?.creationDate) {
timestamp = Math.floor(new Date(current.metadata.creationDate as string).getTime() / 1000);
timestamp = Math.floor(new Date(current.metadata.creationDate).getTime() / 1000);
}

if (current.name && current.meanDuration && current.meanCount && timestamp) {
Expand Down
4 changes: 2 additions & 2 deletions .github/libs/GitUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ function getCommitHistoryAsJSON(fromTag: string, toTag: string): Promise<CommitT
console.log(`Running command: git ${args.join(' ')}`);
const spawnedProcess = spawn('git', args);
spawnedProcess.on('message', console.log);
spawnedProcess.stdout.on('data', (chunk) => {
spawnedProcess.stdout.on('data', (chunk: Buffer) => {
console.log(chunk.toString());
stdout += chunk.toString();
});
spawnedProcess.stderr.on('data', (chunk) => {
spawnedProcess.stderr.on('data', (chunk: Buffer) => {
console.error(chunk.toString());
stderr += chunk.toString();
});
Expand Down
35 changes: 35 additions & 0 deletions .github/scripts/enforceRedirect.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/bash

# HelpDot - Whenever an article is moved/renamed/deleted we should verify that
# we have added a redirect link for it in redirects.csv. This ensures that we don't have broken links.

declare -r RED='\033[0;31m'
declare -r GREEN='\033[0;32m'
declare -r NC='\033[0m'

declare -r ARTICLES_DIRECTORY="docs/articles"
declare -r REDIRECTS_FILE="docs/redirects.csv"

hasRenamedOrDeletedArticle=false
hasModifiedRedirect=false

if git log origin/main..HEAD --name-status --pretty=format: $ARTICLES_DIRECTORY | grep -q -E "^(R|D)"
then
echo "Articles have been renamed/moved/deleted"
hasRenamedOrDeletedArticle=true
fi

if git log origin/main..HEAD --name-status --pretty=format: $REDIRECTS_FILE | grep -q -E "^(M)"
then
echo "Redirects.csv has been modified"
hasModifiedRedirect=true
fi

if [[ $hasRenamedOrDeletedArticle == true && $hasModifiedRedirect == false ]]
then
echo -e "${RED}Articles have been renamed or deleted. Please add a redirect link for the old article links in redirects.csv${NC}"
exit 1
fi

echo -e "${GREEN}Articles aren't moved or deleted, or a redirect has been added. Please verify that a redirect has been added for all the files moved or deleted${NC}"
exit 0
6 changes: 6 additions & 0 deletions .github/workflows/deployExpensifyHelp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@ jobs:
env:
IS_PR_FROM_FORK: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork }}
runs-on: ubuntu-latest
continue-on-error: true
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup NodeJS
uses: ./.github/actions/composite/setupNode
Expand All @@ -42,6 +45,9 @@ jobs:
- name: Check for duplicates and cycles in redirects.csv
run: ./.github/scripts/verifyRedirect.sh

- name: Enforce that a redirect link has been created
run: ./.github/scripts/enforceRedirect.sh

- name: Build with Jekyll
uses: actions/jekyll-build-pages@0143c158f4fa0c5dcd99499a5d00859d79f70b0e
with:
Expand Down
9 changes: 6 additions & 3 deletions .storybook/webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
/* eslint-disable no-param-reassign */

/* eslint-disable @typescript-eslint/naming-convention */
import type Environment from 'config/webpack/types';
import dotenv from 'dotenv';
import path from 'path';
import {DefinePlugin} from 'webpack';
Expand All @@ -18,6 +19,8 @@ type CustomWebpackConfig = {
};
};

type CustomWebpackFunction = ({file, platform}: Environment) => CustomWebpackConfig;

let envFile: string;
switch (process.env.ENV) {
case 'production':
Expand All @@ -31,9 +34,9 @@ switch (process.env.ENV) {
}

const env = dotenv.config({path: path.resolve(__dirname, `../${envFile}`)});
const custom: CustomWebpackConfig = require('../config/webpack/webpack.common').default({
envFile,
});
const customFunction: CustomWebpackFunction = require('../config/webpack/webpack.common').default;

const custom: CustomWebpackConfig = customFunction({file: envFile});

const webpackConfig = ({config}: {config: Configuration}) => {
if (!config.resolve) {
Expand Down
Binary file added assets/animations/Abracadabra.lottie
Binary file not shown.
Binary file added assets/animations/MagicCode.lottie
Binary file not shown.
17 changes: 15 additions & 2 deletions config/webpack/webpack.common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,27 @@ import dotenv from 'dotenv';
import fs from 'fs';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import path from 'path';
import type {Configuration} from 'webpack';
import type {Compiler, Configuration} from 'webpack';
import {DefinePlugin, EnvironmentPlugin, IgnorePlugin, ProvidePlugin} from 'webpack';
import {BundleAnalyzerPlugin} from 'webpack-bundle-analyzer';
import CustomVersionFilePlugin from './CustomVersionFilePlugin';
import type Environment from './types';

// importing anything from @vue/preload-webpack-plugin causes an error
type Options = {
rel: string;
as: string;
fileWhitelist: RegExp[];
include: string;
};

type PreloadWebpackPluginClass = {
new (options?: Options): PreloadWebpackPluginClass;
apply: (compiler: Compiler) => void;
};

// require is necessary, there are no types for this package and the declaration file can't be seen by the build process which causes an error.
const PreloadWebpackPlugin = require('@vue/preload-webpack-plugin');
const PreloadWebpackPlugin: PreloadWebpackPluginClass = require('@vue/preload-webpack-plugin');

const includeModules = [
'react-native-animatable',
Expand Down
8 changes: 7 additions & 1 deletion desktop/createDownloadQueue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ type DownloadItem = {
options: Options;
};

type CreateDownloadQueue = () => {
enqueueDownloadItem: (item: DownloadItem) => void;
dequeueDownloadItem: () => DownloadItem | undefined;
};

/**
* Returns the filename with extension based on the given name and MIME type.
* @param name - The name of the file.
Expand All @@ -28,7 +33,7 @@ const getFilenameFromMime = (name: string, mime: string): string => {
return `${name}.${extensions}`;
};

const createDownloadQueue = () => {
const createDownloadQueue: CreateDownloadQueue = () => {
const downloadItemProcessor = (item: DownloadItem): Promise<void> =>
new Promise((resolve, reject) => {
let downloadTimeout: NodeJS.Timeout;
Expand Down Expand Up @@ -114,3 +119,4 @@ const createDownloadQueue = () => {
};

export default createDownloadQueue;
export type {DownloadItem, CreateDownloadQueue};
5 changes: 3 additions & 2 deletions desktop/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ import CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
import type PlatformSpecificUpdater from '@src/setup/platformSetup/types';
import type {Locale} from '@src/types/onyx';
import type {CreateDownloadQueue, DownloadItem} from './createDownloadQueue';
import ELECTRON_EVENTS from './ELECTRON_EVENTS';

const createDownloadQueue = require('./createDownloadQueue').default;
const createDownloadQueue: CreateDownloadQueue = require('./createDownloadQueue').default;

const port = process.env.PORT ?? 8082;
const {DESKTOP_SHORTCUT_ACCELERATOR, LOCALES} = CONST;
Expand Down Expand Up @@ -617,7 +618,7 @@ const mainWindow = (): Promise<void> => {

const downloadQueue = createDownloadQueue();
ipcMain.on(ELECTRON_EVENTS.DOWNLOAD, (event, downloadData) => {
const downloadItem = {
const downloadItem: DownloadItem = {
...downloadData,
win: browserWindow,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,95 +4,79 @@ description: How to connect a business bank account to New Expensify
---
<div id="new-expensify" markdown="1">

Adding a business bank account unlocks a myriad of features and automation in Expensify, such as:
- Reimburse expenses via direct bank transfer
- Pay bills
- Collect invoice payments
- Issue the Expensify Card

# To connect a bank account
1. Go to **Settings > Workspaces > _Workspace Name_ > Bank account > Connect bank account**
2. Click **Connect online with Plaid**
3. Click **Continue**
4. When you reach the **Plaid** screen, you'll be shown a list of compatible banks that offer direct online login access
5. Login to the business bank account:
- If the bank is not listed, click the X to go back to the connection type
- Here you’ll see the option to **Connect Manually**
- Enter your account and routing numbers
6. Enter your bank login credentials:
- If your bank requires additional security measures, you will be directed to obtain and enter a security code
- If you have more than one account available to choose from, you will be directed to choose the desired account

## Enter company information
This is where you’ll add the legal business name as well as several other company details.

- **Company address**: The company address must be located in the US and a physical location (If you input a maildrop address, PO box, or UPS Store, the address will be flagged for review, and adding the bank account to Expensify will be delayed)
- **Tax Identification Number**: This is the identification number that was assigned to the business by the IRS
- **Company website**: A company website is required to use most of Expensify’s payment features. When adding the website of the business, format it as, https://www.domain.com
- **Industry Classification Code**: You can locate a list of Industry Classification Codes [here]([url](https://www.census.gov/naics/?input=software&year=2022))

## Enter personal information
Whoever is connecting the bank account to Expensify, must enter their details under the Requestor Information section:
- The address must be a physical address
- The address must be located in the US
- The SSN must be US-issued

This does not need to be a signor on the bank account. If someone other than the Expensify account owner enters their personal information in this section, the details will be flagged for review, and adding the bank account to Expensify will be delayed.

## Upload ID
To connect a bank account in New Expensify, you must first enable the Make or Track Payments Workflow.
# Step 1: Enable Make or track payments
1. Head to **Workspaces** > **More Features** > **Enable Workflows**
2. From there, a Workflows setting will appear in the left-hand menu
3. Click on **Workflows**
4. Enable **Make or track payments**

# Step 2: Connect bank account
1. Click Connect bank account
2. Select either Connect online with Plaid (preferred) or Connect manually
3. Enter bank details

# Step 4: Upload ID
After entering your personal details, you’ll be prompted to click a link or scan a QR code so that you can do the following:
1. Upload a photo of the front and back of your ID (this cannot be a photo of an existing image)
2. Use your device to take a selfie and record a short video of yourself
2. Use your device to take a selfie and record a short video of yourself

**Your ID must be:**
- Issued in the US
- Current (ie: the expiration date must be in the future)

## Additional Information
Check the appropriate box under **Additional Information**, accept the agreement terms, and verify that all of the information is true and accurate:
- A Beneficial Owner refers to an **individual** who owns 25% or more of the business.
- If you or another **individual** owns 25% or more of the business, please check the appropriate box
# Step 5: Enter company information
This is where you’ll add the legal business name as well as several other company details.
- **Company address:** The company address must be located in the US and a physical location (If you input a maildrop address, PO box, or UPS Store, the address will be flagged for review, and adding the bank account to Expensify will be delayed)
- **Tax Identification Number:** This is the identification number that was assigned to the business by the IRS
- **Company website:** A company website is required to use most of Expensify’s payment features.
- **Industry Classification Code:** You can locate a list of Industry Classification Codes [here](https://www.census.gov/naics/?input=software&year=2022).

# Step 6: Additional Information
Check the appropriate box under Additional Information, accept the agreement terms, and verify that all of the information is true and accurate:
- A Beneficial Owner refers to an individual who owns 25% or more of the business.
- If you or another individual owns 25% or more of the business, please check the appropriate box
- If someone else owns 25% or more of the business, you will be prompted to provide their personal information

If no individual owns more than 25% of the company you do not need to list any beneficial owners. In that case, be sure to leave both boxes unchecked under the Beneficial Owner Additional Information section.

The details you submitted may require additional review. If that's the case, you'll receive a message from the Concierge outlining the next steps. Otherwise, your bank account will be connected automatically.
The details you submitted may require additional review. If that's the case, you'll receive a message from the Concierge outlining the next steps. Otherwise, your bank account will be connected automatically.

{% include faq-begin.md %}

## What are the general requirements for adding a business bank account?

To add a business bank account to issue reimbursements via ACH (US), to pay invoices (US), or to issue Expensify Cards:
- You must enter a physical address for yourself, any Beneficial Owner (if one exists), and the business associated with the bank account. We **cannot** accept a PO Box or MailDrop location.
If you are adding the bank account to Expensify, you must do so from your Expensify account settings.
- If you are adding a bank account to Expensify, we are required by law to verify your identity. Part of this process requires you to verify a US-issued photo ID. For using features related to US ACH, your ID must be issued by the United States. You and any Beneficial Owner (if one exists), must also have a US address
- You must have a valid website for your business to utilize the Expensify Card, or to pay invoices with Expensify.
To add a business bank account to issue reimbursements via ACH (US) or to issue Expensify Cards:
- You must enter a physical address for yourself, any Beneficial Owner (if one exists), and the business associated with the bank account. We cannot accept a PO Box or MailDrop location.
- If you are adding the bank account to Expensify, we are required by law to verify your identity. Part of this process requires you to verify a US-issued photo ID. Your ID must be issued by the United States to use features related to US ACH. You and any Beneficial Owner (if one exists) must also have a US address.

## What is a Beneficial Owner?

A Beneficial Owner refers to an **individual** who owns 25% or more of the business. If no individual owns 25% or more of the business, the company does not have a Beneficial Owner.

## What do I do if the Beneficial Owner section only asks for personal details, but my organization is owned by another company?

Please indicate you have a Beneficial Owner only if it is an individual who owns 25% or more of the business.
Please indicate you have a Beneficial Owner only if it is an individual who owns 25% or more of the business.

## Why can’t I input my address or upload my ID?

Are you entering a US address? When adding a verified business bank account in Expensify, the individual adding the account and any beneficial owner (if one exists) are required to have a US address, US photo ID, and a US SSN. If you do not meet these requirements, you’ll need to have another admin add the bank account and then share access with you once it is verified.
When adding a verified business bank account in Expensify, the individual adding the account and any beneficial owner (if one exists) are required to have a US address, US photo ID, and a US SSN. If you do not meet these requirements, you’ll need to have another admin add the bank account and then share access with you once it is verified.

## Why am I asked for documents when adding my bank account?

When a bank account is added to Expensify, we complete a series of checks to verify the information provided to us. We conduct these checks to comply with both our sponsor bank's requirements and federal government regulations, specifically the Bank Secrecy Act / Anti-Money Laundering (BSA / AML) laws. Expensify also has anti-fraud measures in place.
If automatic verification fails, we may request manual verification, which could involve documents such as address verification for your business, a letter from your bank confirming bank account ownership, etc.
When a bank account is added to Expensify, we complete a series of checks to verify the information provided to us. We conduct these checks to comply with both our sponsor bank's requirements and federal government regulations, specifically the Bank Secrecy Act / Anti-Money Laundering (BSA / AML) laws. Expensify also has anti-fraud measures in place.

If automatic verification fails, we may request manual verification, which could involve documents such as address verification for your business, a letter from your bank confirming bank account ownership, etc.

If you have any questions regarding the documentation request you received, please contact Concierge and they will be happy to assist.

## I don’t see all three microtransactions I need to validate my bank account. What should I do?

It's a good idea to wait until the end of that second business day. If you still don’t see them, please contact your bank and ask them to whitelist our ACH IDs **1270239450**, **4270239450**, and **2270239450**. Expensify’s ACH Originator Name is "Expensify."
Wait until the end of the second business day. If you still don’t see them, please contact your bank and ask them to whitelist our ACH IDs **1270239450**, **4270239450**, and **2270239450**. Expensify’s ACH Originator Name is "Expensify."

Once that's all set, make sure to contact your account manager or concierge, and our team will be able to re-trigger those three test transactions!


{% include faq-end.md %}

</div>
4 changes: 2 additions & 2 deletions jest/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ jest.mock('react-native-onyx/dist/storage', () => mockStorage);
jest.mock('react-native/Libraries/EventEmitter/NativeEventEmitter');

// Turn off the console logs for timing events. They are not relevant for unit tests and create a lot of noise
jest.spyOn(console, 'debug').mockImplementation((...params) => {
if (params[0].indexOf('Timing:') === 0) {
jest.spyOn(console, 'debug').mockImplementation((...params: string[]) => {
if (params[0].startsWith('Timing:')) {
return;
}

Expand Down
Loading

0 comments on commit dfb0b2c

Please sign in to comment.