first commit
هذا الالتزام موجود في:
13
src/common/utils/cursor.util.spec.ts
Normal file
13
src/common/utils/cursor.util.spec.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { decodeOffsetCursor, encodeOffsetCursor } from './cursor.util';
|
||||
|
||||
describe('cursor util', () => {
|
||||
it('encodes and decodes cursor offsets', () => {
|
||||
const cursor = encodeOffsetCursor(40);
|
||||
expect(decodeOffsetCursor(cursor)).toBe(40);
|
||||
});
|
||||
|
||||
it('returns null on invalid cursor', () => {
|
||||
expect(decodeOffsetCursor('%%%invalid%%%')).toBeNull();
|
||||
expect(decodeOffsetCursor(encodeOffsetCursor(-1))).toBeNull();
|
||||
});
|
||||
});
|
||||
19
src/common/utils/cursor.util.ts
Normal file
19
src/common/utils/cursor.util.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
export const encodeOffsetCursor = (offset: number): string =>
|
||||
Buffer.from(String(offset), 'utf8').toString('base64url');
|
||||
|
||||
export const decodeOffsetCursor = (cursor?: string): number | null => {
|
||||
if (!cursor) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const raw = Buffer.from(cursor, 'base64url').toString('utf8');
|
||||
const parsed = Number(raw);
|
||||
if (!Number.isInteger(parsed) || parsed < 0) {
|
||||
return null;
|
||||
}
|
||||
return parsed;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
7
src/common/utils/hash.util.ts
Normal file
7
src/common/utils/hash.util.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import * as bcrypt from 'bcrypt';
|
||||
|
||||
export const hashValue = async (value: string, saltRounds: number): Promise<string> =>
|
||||
bcrypt.hash(value, saltRounds);
|
||||
|
||||
export const compareHash = async (value: string, hashedValue: string): Promise<boolean> =>
|
||||
bcrypt.compare(value, hashedValue);
|
||||
المرجع في مشكلة جديدة
حظر مستخدم