Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict';

import type { QueryInterface } from 'sequelize';
import { DataTypes } from 'sequelize';

module.exports = {
async up(queryInterface: QueryInterface) {
await queryInterface.addColumn('ManualPaymentProviders', 'referenceTemplate', {
type: DataTypes.TEXT,
allowNull: true,
});
},

async down(queryInterface: QueryInterface) {
await queryInterface.removeColumn('ManualPaymentProviders', 'referenceTemplate');
},
};
15 changes: 15 additions & 0 deletions server/graphql/schemaV2.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -8239,6 +8239,11 @@
"""
accountDetails: JSON

"""
Plain-text template used to build the payment reference shown as {reference} in instructions (default {contributionId})
"""
referenceTemplate: String

Check notice on line 8245 in server/graphql/schemaV2.graphql

View workflow job for this annotation

GitHub Actions / GraphQL Inspector - Schema v2

Field 'referenceTemplate' was added to object type 'ManualPaymentProvider'

Field 'referenceTemplate' was added to object type 'ManualPaymentProvider'

"""
Whether this provider has been archived
"""
Expand Down Expand Up @@ -26829,6 +26834,11 @@
Bank account details for BANK_TRANSFER type providers
"""
accountDetails: JSON

"""
Plain-text template for the payment reference (e.g. {contributionId}). Variables: amount, collective, OrderId, contributionId, account. Do not use {reference} here.
"""
referenceTemplate: String

Check warning on line 26841 in server/graphql/schemaV2.graphql

View workflow job for this annotation

GitHub Actions / GraphQL Inspector - Schema v2

Input field 'referenceTemplate' was added to input object type 'ManualPaymentProviderCreateInput'

Input field 'referenceTemplate' was added to input object type 'ManualPaymentProviderCreateInput'
}

input ManualPaymentProviderUpdateInput {
Expand All @@ -26851,6 +26861,11 @@
Bank account details for BANK_TRANSFER type providers
"""
accountDetails: JSON

"""
Plain-text template for the payment reference (e.g. {contributionId}). Variables: amount, collective, OrderId, contributionId, account. Do not use {reference} here.
"""
referenceTemplate: String

Check warning on line 26868 in server/graphql/schemaV2.graphql

View workflow job for this annotation

GitHub Actions / GraphQL Inspector - Schema v2

Input field 'referenceTemplate' was added to input object type 'ManualPaymentProviderUpdateInput'

Input field 'referenceTemplate' was added to input object type 'ManualPaymentProviderUpdateInput'
}

type FollowAccountResult {
Expand Down
10 changes: 10 additions & 0 deletions server/graphql/v2/input/ManualPaymentProviderInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ export const GraphQLManualPaymentProviderCreateInput = new GraphQLInputObjectTyp
type: GraphQLJSON,
description: 'Bank account details for BANK_TRANSFER type providers',
},
referenceTemplate: {
type: GraphQLString,
description:
'Plain-text template for the payment reference (e.g. {contributionId}). Variables: amount, collective, OrderId, contributionId, account. Do not use {reference} here.',
},
}),
});

Expand All @@ -74,6 +79,11 @@ export const GraphQLManualPaymentProviderUpdateInput = new GraphQLInputObjectTyp
type: GraphQLJSON,
description: 'Bank account details for BANK_TRANSFER type providers',
},
referenceTemplate: {
type: GraphQLString,
description:
'Plain-text template for the payment reference (e.g. {contributionId}). Variables: amount, collective, OrderId, contributionId, account. Do not use {reference} here.',
},
}),
});

Expand Down
2 changes: 2 additions & 0 deletions server/graphql/v2/mutation/ManualPaymentProviderMutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ const manualPaymentProviderMutations = {
instructions: args.manualPaymentProvider.instructions,
icon: args.manualPaymentProvider.icon,
data: args.manualPaymentProvider.accountDetails,
referenceTemplate: args.manualPaymentProvider.referenceTemplate,
order: (maxOrder || 0) + 1,
},
{ transaction },
Expand Down Expand Up @@ -125,6 +126,7 @@ const manualPaymentProviderMutations = {
instructions: args.input.instructions,
icon: args.input.icon,
data: args.input.accountDetails,
referenceTemplate: args.input.referenceTemplate,
},
isUndefined,
),
Expand Down
6 changes: 6 additions & 0 deletions server/graphql/v2/object/ManualPaymentProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ export const GraphQLManualPaymentProvider = new GraphQLObjectType({
description: 'Bank account details for BANK_TRANSFER type providers',
resolve: provider => (provider.type === ManualPaymentProviderTypes.BANK_TRANSFER ? provider.data : null),
},
referenceTemplate: {
type: GraphQLString,
description:
'Plain-text template used to build the payment reference shown as {reference} in instructions (default {contributionId})',
resolve: provider => provider.referenceTemplate ?? '{contributionId}',
},
isArchived: {
type: new GraphQLNonNull(GraphQLBoolean),
description: 'Whether this provider has been archived',
Expand Down
23 changes: 22 additions & 1 deletion server/models/ManualPaymentProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from 'sequelize';

import { EntityShortIdPrefix } from '../lib/permalink/entity-map';
import { optsSanitizedSimplifiedWithImages, sanitizeHTML } from '../lib/sanitize-html';
import { optsSanitizedSimplifiedWithImages, sanitizeHTML, stripHTML } from '../lib/sanitize-html';
import sequelize from '../lib/sequelize';
import { RecipientAccount } from '../types/transferwise';

Expand All @@ -30,6 +30,14 @@ export enum ManualPaymentProviderTypes {
export const sanitizeManualPaymentProviderInstructions = (instructions: string): string =>
sanitizeHTML(instructions, optsSanitizedSimplifiedWithImages);

/**
* Plain-text template for payment reference (no HTML); strips tags for safety.
*/
export const sanitizeManualPaymentProviderReferenceTemplate = (value: string): string | null => {
const trimmed = stripHTML(value ?? '').trim();
return trimmed === '' ? null : trimmed;
};

/**
* Sequelize model to represent a ManualPaymentProvider, linked to the `ManualPaymentProviders` table.
* These are custom payment methods that hosts can define for contributors to use when making
Expand All @@ -49,6 +57,7 @@ class ManualPaymentProvider extends ModelWithPublicId<
declare public instructions: string;
declare public icon: CreationOptional<string>;
declare public data: CreationOptional<RecipientAccount | Record<string, unknown>>;
declare public referenceTemplate: CreationOptional<string | null>;
declare public order: CreationOptional<number>;
declare public archivedAt: CreationOptional<Date>;
declare public createdAt: CreationOptional<Date>;
Expand Down Expand Up @@ -88,6 +97,7 @@ class ManualPaymentProvider extends ModelWithPublicId<
instructions: this.instructions,
icon: this.icon,
data: this.data,
referenceTemplate: this.referenceTemplate,
order: this.order,
archivedAt: this.archivedAt,
};
Expand Down Expand Up @@ -148,6 +158,17 @@ ManualPaymentProvider.init(
type: DataTypes.JSONB,
allowNull: true,
},
referenceTemplate: {
type: DataTypes.TEXT,
allowNull: true,
set(value: string | null | undefined) {
if (value === null || value === undefined) {
this.setDataValue('referenceTemplate', null);
} else {
this.setDataValue('referenceTemplate', sanitizeManualPaymentProviderReferenceTemplate(value));
}
},
},
order: {
type: DataTypes.INTEGER,
allowNull: false,
Expand Down
1 change: 1 addition & 0 deletions test/test-helpers/fake-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1433,6 +1433,7 @@ export const fakeManualPaymentProvider = async (
instructions: string;
icon: string;
data: Record<string, unknown>;
referenceTemplate: string | null;
order: number;
archivedAt: Date;
}> = {},
Expand Down
Loading