feat(brand): rebrand to Hedena Gold and bring main user-app chrome
Rename the brand, ship Hedena logos, persist login OTP text in the SMS list, and port home/nav/auth/theme polish from main while keeping expert customers intact. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -8,7 +8,7 @@ import { envOr } from './env';
|
||||
* docs/BRANDING.md for the full list.
|
||||
*/
|
||||
export function brandName(): string {
|
||||
return envOr('BRAND_NAME', 'تهران تاج');
|
||||
return envOr('BRAND_NAME', 'هدناگلد');
|
||||
}
|
||||
|
||||
export function brandSiteUrl(): string {
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
UnauthorizedException,
|
||||
} from '@nestjs/common';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import { AdminRole, CustomerKind, MessageAudience, Prisma, VerificationStep } from '@prisma/client';
|
||||
import { AdminRole, CustomerKind, Prisma, VerificationStep } from '@prisma/client';
|
||||
import * as bcrypt from 'bcryptjs';
|
||||
import { PrismaService } from '../../prisma/prisma.service';
|
||||
import {
|
||||
@@ -887,10 +887,9 @@ export class CustomerAuthService {
|
||||
`رمز عبور یکبار مصرف شما جهت ورود به اپلیکیشن ${brandName()} ${code} می باشد\n` +
|
||||
`aMo6iFyUQaY`;
|
||||
|
||||
// persist:false — the real text carries the live code, and the admin SMS
|
||||
// grid lists and searches `body` (SEC-11). The redacted audit row below
|
||||
// takes its place.
|
||||
const result = await this.sms.send(mobile, smsText, { persist: false });
|
||||
// Persist the real OTP body so the admin SMS list can show login codes
|
||||
// (owner request: operators need to read them; risk accepted).
|
||||
const result = await this.sms.send(mobile, smsText);
|
||||
|
||||
// Only outside production, and only when no gateway is configured, so a
|
||||
// deployment can never print live codes into its logs.
|
||||
@@ -928,22 +927,6 @@ export class CustomerAuthService {
|
||||
HttpStatus.SERVICE_UNAVAILABLE,
|
||||
);
|
||||
}
|
||||
|
||||
// An audit row, NOT the message body.
|
||||
//
|
||||
// SmsMessage.body is listed and full-text searchable on the admin panel's
|
||||
// SMS grid (admin-misc.service.ts:136 allows `body`, :135 searches it), so
|
||||
// persisting the real text would show every live OTP to any operator
|
||||
// holding the `sms` rid — and the whole point of hashing codeHash is that
|
||||
// the code exists nowhere in readable form. The code is redacted here.
|
||||
await this.prisma.smsMessage.create({
|
||||
data: {
|
||||
audience: MessageAudience.SINGLE_NUMBER,
|
||||
recipients: mobile,
|
||||
body: 'کد یکبار مصرف ورود (متن پیام ثبت نمیشود)',
|
||||
sentCount: 1,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -334,7 +334,7 @@ describe('OrdersService.createOrder — order SMS', () => {
|
||||
await service.createOrder(dto, 'c1', { placedBy: 'customer' });
|
||||
await settle();
|
||||
const toCustomer = sent.find((s) => s.to === '09120000001');
|
||||
expect(toCustomer?.body).toContain('به ثبت رسید. تهران تاج');
|
||||
expect(toCustomer?.body).toContain('به ثبت رسید. هدناگلد');
|
||||
expect(toCustomer?.body).not.toContain('معلق');
|
||||
});
|
||||
|
||||
|
||||
@@ -310,18 +310,18 @@ describe('SmsService.send', () => {
|
||||
|
||||
/**
|
||||
* The OTP text keeps the reference's shape (ApiMobileController.php:47) with
|
||||
* the brand تهران تاج — the first line and the trailing token are the Android SMS
|
||||
* the brand هدناگلد — the first line and the trailing token are the Android SMS
|
||||
* Retriever hash, and autofill breaks if either changes.
|
||||
*/
|
||||
describe('OTP message template', () => {
|
||||
const build = (code: string) =>
|
||||
`<#> code is ${code}\n` +
|
||||
`رمز عبور یکبار مصرف شما جهت ورود به اپلیکیشن تهران تاج ${code} می باشد\n` +
|
||||
`رمز عبور یکبار مصرف شما جهت ورود به اپلیکیشن هدناگلد ${code} می باشد\n` +
|
||||
`aMo6iFyUQaY`;
|
||||
|
||||
it('matches the expected text byte for byte', () => {
|
||||
expect(build('1234')).toBe(
|
||||
'<#> code is 1234\nرمز عبور یکبار مصرف شما جهت ورود به اپلیکیشن تهران تاج 1234 می باشد\naMo6iFyUQaY',
|
||||
'<#> code is 1234\nرمز عبور یکبار مصرف شما جهت ورود به اپلیکیشن هدناگلد 1234 می باشد\naMo6iFyUQaY',
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -14,12 +14,10 @@ import { isPrivateIpv4, resolveRelayHost } from './drivers/relay.driver';
|
||||
*
|
||||
* Reference behaviour kept for every driver:
|
||||
* * the message is trim()ed before sending (`Sms.php:77`)
|
||||
* * EVERY message is persisted, via `Sms::set()` (`:80`)
|
||||
* * EVERY message is persisted, via `Sms::set()` (`:80`) — including OTP
|
||||
* login texts (owner request: show codes in the admin SMS list)
|
||||
* * the response body is returned and the callers ignore it
|
||||
*
|
||||
* The OTP message body is NOT persisted in readable form — see
|
||||
* CustomerAuthService.deliver() and SEC-11.
|
||||
*
|
||||
* Failure handling matches the reference: `Sms::Send` is called inline and its
|
||||
* result is discarded, so a failed send never aborted the order, the document
|
||||
* approval or the customer creation that triggered it. `send()` therefore
|
||||
@@ -31,7 +29,7 @@ export type { SmsSendResult } from './drivers';
|
||||
export interface SmsSendOptions {
|
||||
/**
|
||||
* Persist the message body. Default true, matching `Sms::set()`.
|
||||
* OTP delivery passes false and writes its own redacted row (SEC-11).
|
||||
* Pass false only when the caller writes its own audit row.
|
||||
*/
|
||||
persist?: boolean;
|
||||
audience?: MessageAudience;
|
||||
|
||||
Reference in New Issue
Block a user