pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/HabitRPG/habitica/pull/15466/commits/72200060fa6f128ba1284311ff14e7e4f28bb1f5

s://github.githubassets.com/assets/global-d10a1ef1d5e1.css" /> Phillip/admin deleter by phillipthelen · Pull Request #15466 · HabitRPG/habitica · GitHub
Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
b00f463
refactor sending jobs to worker server
phillipthelen May 13, 2025
6b8e6ed
remove unused imports
phillipthelen May 13, 2025
6ebf3d0
add delete button to adminpanel
phillipthelen May 29, 2025
5540c6e
June 2025 content build (#15437)
CuriousMagpie May 13, 2025
eede13f
fix(script): don't use extremely costly regex
SabreCat May 19, 2025
aa8af15
fix(logging): don't spam empty error events
SabreCat May 19, 2025
b2b2d0f
Translated using Weblate (Ukrainian)
weblate May 19, 2025
7c81b71
5.36.4
SabreCat May 19, 2025
cb2b837
chore(deps): bump serialize-javascript in /website/client (#15395)
dependabot[bot] May 20, 2025
fcb1d06
chore(deps-dev): bump axios from 1.7.4 to 1.8.2 (#15401)
dependabot[bot] May 20, 2025
625db6b
chore(deps): bump prismjs from 1.29.0 to 1.30.0 (#15403)
dependabot[bot] May 20, 2025
787f64a
chore(deps): bump @babel/runtime-corejs2 in /website/client (#15406)
dependabot[bot] May 20, 2025
a3b3b28
chore(deps): bump @babel/helpers in /website/client (#15407)
dependabot[bot] May 20, 2025
0e99142
chore(deps): bump @babel/runtime from 7.23.9 to 7.26.10 (#15410)
dependabot[bot] May 20, 2025
b959731
chore(deps): bump http-proxy-middleware in /website/client (#15427)
dependabot[bot] May 20, 2025
7dd3ca4
Optimize database access for some use cases (#15444)
phillipthelen May 29, 2025
1aba2be
correct worker call
phillipthelen May 29, 2025
bc77c76
remove unused priority
phillipthelen May 29, 2025
0a6f138
fix tests
phillipthelen May 29, 2025
f33e256
don’t use body with delete
phillipthelen May 29, 2025
f4f964b
Merge remote-tracking branch 'origen/develop' into phillip/admin_deleter
phillipthelen Aug 8, 2025
9b52198
Merge branch 'phillip/admin_deleter' of github.com:HabitRPG/habitica …
phillipthelen Aug 8, 2025
71c2e19
add detailed information about sub payment for google and apple
phillipthelen Aug 11, 2025
ba99a65
Support paypal details for subscription in admin panel
phillipthelen Aug 11, 2025
c00aaec
stripe payment details
phillipthelen Aug 11, 2025
af3c37a
fix imports
phillipthelen Aug 11, 2025
7220006
fix tests
phillipthelen Aug 11, 2025
18239b7
fix deleting account
phillipthelen Aug 18, 2025
91ccba9
begin building group admin panel
phillipthelen Aug 19, 2025
6409c4c
fix convertig sub to group plan
phillipthelen Aug 19, 2025
5ba6d24
improve sub status display
phillipthelen Aug 19, 2025
5dbd10e
fix lint
phillipthelen Aug 19, 2025
2e4c0e1
fix long line
phillipthelen Aug 19, 2025
ef66387
fix sub state display
phillipthelen Aug 19, 2025
0e8ca11
lint fix
phillipthelen Aug 19, 2025
375ca3e
fix
phillipthelen Aug 19, 2025
02d4d2d
delete amplitude data by default
phillipthelen Aug 19, 2025
58ec028
improve searching for email in admin panel
phillipthelen Aug 20, 2025
92b4c10
correctly call method
phillipthelen Aug 20, 2025
faa1db4
move delete button in admin panel
phillipthelen Aug 20, 2025
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
Prev Previous commit
Next Next commit
fix tests
  • Loading branch information
phillipthelen committed Aug 11, 2025
commit 72200060fa6f128ba1284311ff14e7e4f28bb1f5
92 changes: 53 additions & 39 deletions test/api/unit/libs/payments/google.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,36 @@ const { i18n } = common;

describe('Google Payments', () => {
const subKey = 'basic_3mo';
let iapSetupStub;
let iapValidateStub;
let iapIsValidatedStub;
let paymentBuySkuStub;
let validateGiftMessageStub;

beforeEach(() => {
iapSetupStub = sinon.stub(iap, 'setup')
.resolves();
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
.returns(true);
sinon.stub(iap, 'isCanceled').returns(false);
sinon.stub(iap, 'isExpired').returns(false);
paymentBuySkuStub = sinon.stub(payments, 'buySkuItem').resolves({});
validateGiftMessageStub = sinon.stub(gems, 'validateGiftMessage');
});

afterEach(() => {
iap.setup.restore();
iap.validate.restore();
iap.isValidated.restore();
iap.isCanceled.restore();
iap.isExpired.restore();
payments.buySkuItem.restore();
gems.validateGiftMessage.restore();
});

describe('verifyPurchase', () => {
let sku; let user; let token; let receipt; let signature; let
headers;
let iapSetupStub; let iapValidateStub; let iapIsValidatedStub; let
paymentBuySkuStub; let validateGiftMessageStub;

beforeEach(() => {
sku = 'com.habitrpg.android.habitica.iap.21gems';
Expand All @@ -25,21 +49,7 @@ describe('Google Payments', () => {
signature = '';
headers = {};

iapSetupStub = sinon.stub(iap, 'setup')
.resolves();
iapValidateStub = sinon.stub(iap, 'validate').resolves({ productId: sku });
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
.returns(true);
paymentBuySkuStub = sinon.stub(payments, 'buySkuItem').resolves({});
validateGiftMessageStub = sinon.stub(gems, 'validateGiftMessage');
});

afterEach(() => {
iap.setup.restore();
iap.validate.restore();
iap.isValidated.restore();
payments.buySkuItem.restore();
gems.validateGiftMessage.restore();
});

it('should throw an error if receipt is invalid', async () => {
Expand Down Expand Up @@ -160,8 +170,7 @@ describe('Google Payments', () => {
describe('subscribe', () => {
let sub; let sku; let user; let token; let receipt; let signature; let headers; let
nextPaymentProcessing;
let iapSetupStub; let iapValidateStub; let iapIsValidatedStub; let
paymentsCreateSubscritionStub;
let paymentsCreateSubscritionStub;

beforeEach(() => {
sub = common.content.subscriptionBlocks[subKey];
Expand All @@ -173,19 +182,12 @@ describe('Google Payments', () => {
signature = '';
nextPaymentProcessing = moment.utc().add({ days: 2 });

iapSetupStub = sinon.stub(iap, 'setup')
.resolves();
iapValidateStub = sinon.stub(iap, 'validate')
.resolves({});
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
.returns(true);
paymentsCreateSubscritionStub = sinon.stub(payments, 'createSubscription').resolves({});
});

afterEach(() => {
iap.setup.restore();
iap.validate.restore();
iap.isValidated.restore();
payments.createSubscription.restore();
});

Expand Down Expand Up @@ -243,7 +245,7 @@ describe('Google Payments', () => {
describe('cancelSubscribe ', () => {
let user; let token; let receipt; let signature; let headers; let customerId; let
expirationDate;
let iapSetupStub; let iapValidateStub; let iapIsValidatedStub; let iapGetPurchaseDataStub; let
let iapGetPurchaseDataStub; let
paymentCancelSubscriptionSpy;

beforeEach(async () => {
Expand All @@ -253,17 +255,12 @@ describe('Google Payments', () => {
signature = '';
customerId = 'test-customerId';
expirationDate = moment.utc();

iapSetupStub = sinon.stub(iap, 'setup')
.resolves();
iapValidateStub = sinon.stub(iap, 'validate')
.resolves({
expirationDate,
});
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
.returns([{ expirationDate: expirationDate.toDate(), autoRenewing: false }]);
iapIsValidatedStub = sinon.stub(iap, 'isValidated')
.returns(true);

user = new User();
user.profile.name = 'sender';
Expand All @@ -276,9 +273,6 @@ describe('Google Payments', () => {
});

afterEach(() => {
iap.setup.restore();
iap.validate.restore();
iap.isValidated.restore();
iap.getPurchaseData.restore();
payments.cancelSubscription.restore();
});
Expand Down Expand Up @@ -308,6 +302,8 @@ describe('Google Payments', () => {
});

it('should cancel a user subscription', async () => {
iap.isCanceled.restore();
iap.isCanceled = sinon.stub(iap, 'isCanceled').returns(true);
await googlePayments.cancelSubscribe(user, headers);

expect(iapSetupStub).to.be.calledOnce;
Expand All @@ -332,11 +328,20 @@ describe('Google Payments', () => {
});

it('should cancel a user subscription with multiple inactive subscriptions', async () => {
iap.isCanceled.restore();
iap.isCanceled = sinon.stub(iap, 'isCanceled').returns(true);
const laterDate = moment.utc().add(7, 'days');
iap.getPurchaseData.restore();
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
.returns([{ expirationDate, autoRenewing: false },
{ expirationDate: laterDate, autoRenewing: false },
.returns([{
startTimeMillis: expirationDate.valueOf(),
expirationDate,
autoRenewing: false,
}, {
startTimeMillis: laterDate.valueOf(),
expirationDate: laterDate,
autoRenewing: false,
},
]);
await googlePayments.cancelSubscribe(user, headers);

Expand Down Expand Up @@ -365,7 +370,12 @@ describe('Google Payments', () => {
iap.getPurchaseData.restore();
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
.returns([{ autoRenewing: true }]);
await googlePayments.cancelSubscribe(user, headers);
await expect(googlePayments.cancelSubscribe(user, headers))
.to.eventually.be.rejected.and.to.eql({
httpCode: 401,
name: 'NotAuthorized',
message: googlePayments.constants.RESPONSE_STILL_VALID,
});

expect(iapSetupStub).to.be.calledOnce;
expect(iapValidateStub).to.be.calledOnce;
Expand All @@ -388,8 +398,12 @@ describe('Google Payments', () => {
.returns([{ expirationDate, autoRenewing: false },
{ autoRenewing: true },
{ expirationDate, autoRenewing: false }]);
await googlePayments.cancelSubscribe(user, headers);

await expect(googlePayments.cancelSubscribe(user, headers))
.to.eventually.be.rejected.and.to.eql({
httpCode: 401,
name: 'NotAuthorized',
message: googlePayments.constants.RESPONSE_STILL_VALID,
});
expect(iapSetupStub).to.be.calledOnce;
expect(iapValidateStub).to.be.calledOnce;
expect(iapValidateStub).to.be.calledWith(iap.GOOGLE, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@
v-if="paymentDetails">
<div
v-for="(value, key) in paymentDetails"
:key="key"
class="form-group row">
<label class="col-sm-3 col-form-label">
{{ getHumandReadablePaymentDetails(key).label }}:
Expand Down Expand Up @@ -578,7 +579,6 @@ import { getPlanContext } from '@/../../common/script/cron';
import subscriptionBlocks from '@/../../common/script/content/subscriptionBlocks';
import saveHero from '../mixins/saveHero';
import LoadingSpinner from '@/components/ui/loadingSpinner';
import { get } from 'lodash';

const PLAY_CONSOLE_ORDERS_BASE_URL = import.meta.env.PLAY_CONSOLE_ORDERS_BASE_URL;

Expand Down Expand Up @@ -627,7 +627,7 @@ const humandReadablePaymentDetails = {
label: 'Failed Payments',
help: 'Number of times the payment failed for this subscription.',
},
}
};

export default {
components: {
Expand Down Expand Up @@ -690,7 +690,7 @@ export default {
},
playOrdersUrl () {
return `${PLAY_CONSOLE_ORDERS_BASE_URL}${this.paymentDetails?.transactionId || ''}`;
}
},
},
methods: {
dateFormat (date) {
Expand Down Expand Up @@ -723,14 +723,14 @@ export default {
},
getSubscriptionPaymentDetails () {
this.$store.dispatch('adminPanel:getSubscriptionPaymentDetails', { userIdentifier: this.hero._id })
.then((details) => {
.then(details => {
if (details) {
this.paymentDetails = details
this.paymentDetails = details;
} else {
alert('No payment details found.');
}
})
.catch((error) => {
.catch(error => {
console.error('Error fetching subscription payment details:', error);
alert(`Failed to fetch payment details: ${error.message || 'Unknown error'}`);
});
Expand Down Expand Up @@ -761,7 +761,7 @@ export default {
},
formatDate (date) {
return date ? moment(date).format('MM/DD/YYYY') : '---';
}
},
},
};
</script>
2 changes: 1 addition & 1 deletion website/client/src/store/actions/adminPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ export async function getSubscriptionPaymentDetails (store, payload) {
const url = `/api/v4/admin/user/${payload.userIdentifier}/subscription-payment-details`;
const response = await axios.get(url);
return response.data.data;
}
}
7 changes: 6 additions & 1 deletion website/server/libs/payments/apple.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,12 @@ async function findSubscriptionPurchase (receipt, onlyActive = true) {
let newestDate;

for (const purchaseData of purchaseDataList) {
const datePurchased = new Date(Number(purchaseData.purchaseDateMs));
let datePurchased;
if (purchaseData.purchaseDate instanceof Date) {
datePurchased = purchaseData.purchaseDate;
} else {
datePurchased = new Date(Number(purchaseData.purchaseDateMs || purchaseData.purchaseDate));
}
const dateTerminated = new Date(Number(purchaseData.expirationDate || 0));
if ((!newestDate || datePurchased > newestDate)) {
if (!onlyActive || dateTerminated > new Date()) {
Expand Down
4 changes: 2 additions & 2 deletions website/server/libs/payments/google.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ async function findSubscriptionPurchase (additionalData) {
const googleRes = await iap.validate(iap.GOOGLE, additionalData);

const isValidated = iap.isValidated(googleRes);
if (!isValidated) throw new NotAuthorized(this.constants.RESPONSE_INVALID_RECEIPT);
if (!isValidated) throw new NotAuthorized(api.constants.RESPONSE_INVALID_RECEIPT);

const purchases = iap.getPurchaseData(googleRes);
if (purchases.length === 0) throw new NotAuthorized(this.constants.RESPONSE_INVALID_RECEIPT);
if (purchases.length === 0) throw new NotAuthorized(api.constants.RESPONSE_INVALID_RECEIPT);

let purchase;
let newestDate;
Expand Down
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy