@thezelijah/majik-message 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/core/compressor/majik-compressor.d.ts +17 -0
- package/dist/core/compressor/majik-compressor.js +86 -0
- package/dist/core/crypto/keystore.js +12 -0
- package/dist/core/database/chat/majik-message-chat.d.ts +94 -0
- package/dist/core/database/chat/majik-message-chat.js +432 -0
- package/dist/core/database/chat/types.d.ts +11 -0
- package/dist/core/database/chat/types.js +1 -0
- package/dist/core/database/system/identity.d.ts +61 -0
- package/dist/core/database/system/identity.js +170 -0
- package/dist/core/database/system/majik-user/enums.d.ts +44 -0
- package/dist/core/database/system/majik-user/enums.js +40 -0
- package/dist/core/database/system/majik-user/majik-user.d.ts +257 -0
- package/dist/core/database/system/majik-user/majik-user.js +812 -0
- package/dist/core/database/system/majik-user/types.d.ts +186 -0
- package/dist/core/database/system/majik-user/types.js +1 -0
- package/dist/core/database/system/majik-user/utils.d.ts +32 -0
- package/dist/core/database/system/majik-user/utils.js +110 -0
- package/dist/core/database/system/utils.d.ts +1 -0
- package/dist/core/database/system/utils.js +8 -0
- package/dist/core/types.d.ts +3 -0
- package/dist/core/utils/idb-majik-system.d.ts +5 -5
- package/dist/core/utils/utilities.d.ts +7 -0
- package/dist/core/utils/utilities.js +14 -0
- package/dist/majik-message.d.ts +18 -0
- package/dist/majik-message.js +101 -0
- package/package.json +2 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { MajikUser } from "./majik-user/majik-user";
|
|
2
|
+
import { MajikContact } from "../../contacts/majik-contact";
|
|
3
|
+
export interface MajikMessageIdentityJSON {
|
|
4
|
+
id: string;
|
|
5
|
+
user_id: string;
|
|
6
|
+
public_key: string;
|
|
7
|
+
phash: string;
|
|
8
|
+
label: string;
|
|
9
|
+
timestamp: string;
|
|
10
|
+
restricted: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* MajikMessageIdentity
|
|
14
|
+
* Immutable identity container with integrity verification
|
|
15
|
+
*/
|
|
16
|
+
export declare class MajikMessageIdentity {
|
|
17
|
+
private readonly _id;
|
|
18
|
+
private readonly _userId;
|
|
19
|
+
private readonly _publicKey;
|
|
20
|
+
private readonly _phash;
|
|
21
|
+
private _label;
|
|
22
|
+
private readonly _timestamp;
|
|
23
|
+
private readonly _restricted;
|
|
24
|
+
/**
|
|
25
|
+
* Constructor is private to enforce controlled creation
|
|
26
|
+
*/
|
|
27
|
+
private constructor();
|
|
28
|
+
/**
|
|
29
|
+
* Create a new immutable identity from MajikUser
|
|
30
|
+
*/
|
|
31
|
+
static create(user: MajikUser, account: MajikContact, options?: {
|
|
32
|
+
label?: string;
|
|
33
|
+
restricted?: boolean;
|
|
34
|
+
}): MajikMessageIdentity;
|
|
35
|
+
get id(): string;
|
|
36
|
+
get userID(): string;
|
|
37
|
+
get publicKey(): string;
|
|
38
|
+
get phash(): string;
|
|
39
|
+
get label(): string;
|
|
40
|
+
get timestamp(): string;
|
|
41
|
+
get restricted(): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Only mutable field
|
|
44
|
+
*/
|
|
45
|
+
set label(label: string);
|
|
46
|
+
/**
|
|
47
|
+
* Returns true if identity is restricted
|
|
48
|
+
*/
|
|
49
|
+
isRestricted(): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Verify identity integrity
|
|
52
|
+
* Detects tampering of id/public_key
|
|
53
|
+
*/
|
|
54
|
+
validateIntegrity(): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Explicit verification helper
|
|
57
|
+
*/
|
|
58
|
+
matches(userId: string, publicKey: string): boolean;
|
|
59
|
+
toJSON(): MajikMessageIdentityJSON;
|
|
60
|
+
static fromJSON(json: string | MajikMessageIdentityJSON): MajikMessageIdentity;
|
|
61
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import crypto from "crypto";
|
|
2
|
+
import { autogenerateID } from "./utils";
|
|
3
|
+
/**
|
|
4
|
+
* Utility assertions
|
|
5
|
+
*/
|
|
6
|
+
function assert(condition, message) {
|
|
7
|
+
if (!condition)
|
|
8
|
+
throw new Error(message);
|
|
9
|
+
}
|
|
10
|
+
function assertString(value, field) {
|
|
11
|
+
assert(typeof value === "string" && value.trim().length > 0, `${field} must be a non-empty string`);
|
|
12
|
+
}
|
|
13
|
+
function assertISODate(value, field) {
|
|
14
|
+
const date = new Date(value);
|
|
15
|
+
assert(!isNaN(date.getTime()), `${field} must be a valid ISO timestamp`);
|
|
16
|
+
}
|
|
17
|
+
function sha256(input) {
|
|
18
|
+
return crypto.createHash("sha256").update(input).digest("hex");
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* MajikMessageIdentity
|
|
22
|
+
* Immutable identity container with integrity verification
|
|
23
|
+
*/
|
|
24
|
+
export class MajikMessageIdentity {
|
|
25
|
+
// 🔒 Private backing fields
|
|
26
|
+
_id;
|
|
27
|
+
_userId;
|
|
28
|
+
_publicKey;
|
|
29
|
+
_phash;
|
|
30
|
+
_label;
|
|
31
|
+
_timestamp;
|
|
32
|
+
_restricted;
|
|
33
|
+
/**
|
|
34
|
+
* Constructor is private to enforce controlled creation
|
|
35
|
+
*/
|
|
36
|
+
constructor(params) {
|
|
37
|
+
assertString(params.id, "id");
|
|
38
|
+
assertString(params.userId, "user_id");
|
|
39
|
+
assertString(params.publicKey, "public_key");
|
|
40
|
+
assertString(params.phash, "phash");
|
|
41
|
+
assertString(params.label, "label");
|
|
42
|
+
assertISODate(params.timestamp, "timestamp");
|
|
43
|
+
assert(typeof params.restricted === "boolean", "restricted must be boolean");
|
|
44
|
+
this._id = params.id;
|
|
45
|
+
this._userId = params.userId;
|
|
46
|
+
this._publicKey = params.publicKey;
|
|
47
|
+
this._phash = params.phash;
|
|
48
|
+
this._label = params.label;
|
|
49
|
+
this._timestamp = params.timestamp;
|
|
50
|
+
this._restricted = params.restricted;
|
|
51
|
+
// Final integrity check at construction
|
|
52
|
+
assert(this.validateIntegrity(), "Identity integrity validation failed");
|
|
53
|
+
}
|
|
54
|
+
// ─────────────────────────────
|
|
55
|
+
// Static factory
|
|
56
|
+
// ─────────────────────────────
|
|
57
|
+
/**
|
|
58
|
+
* Create a new immutable identity from MajikUser
|
|
59
|
+
*/
|
|
60
|
+
static create(user, account, options) {
|
|
61
|
+
assert(user, "MajikUser is required");
|
|
62
|
+
const userValidResult = user.validate();
|
|
63
|
+
if (!userValidResult.isValid) {
|
|
64
|
+
throw new Error(`Invalid MajikUser: ${userValidResult.errors.join(", ")}`);
|
|
65
|
+
}
|
|
66
|
+
const label = options?.label || account?.meta?.label || user.displayName;
|
|
67
|
+
assertString(label, "label");
|
|
68
|
+
const generatedID = autogenerateID();
|
|
69
|
+
const timestamp = new Date().toISOString();
|
|
70
|
+
const phash = sha256(`${user.id}:${account.id}:${generatedID}`);
|
|
71
|
+
return new MajikMessageIdentity({
|
|
72
|
+
id: generatedID,
|
|
73
|
+
userId: user.id,
|
|
74
|
+
publicKey: account.id,
|
|
75
|
+
phash,
|
|
76
|
+
label,
|
|
77
|
+
timestamp,
|
|
78
|
+
restricted: options?.restricted ?? false,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
// ─────────────────────────────
|
|
82
|
+
// Getters (safe, read-only)
|
|
83
|
+
// ─────────────────────────────
|
|
84
|
+
get id() {
|
|
85
|
+
return this._id;
|
|
86
|
+
}
|
|
87
|
+
get userID() {
|
|
88
|
+
return this._userId;
|
|
89
|
+
}
|
|
90
|
+
get publicKey() {
|
|
91
|
+
return this._publicKey;
|
|
92
|
+
}
|
|
93
|
+
get phash() {
|
|
94
|
+
return this._phash;
|
|
95
|
+
}
|
|
96
|
+
get label() {
|
|
97
|
+
return this._label;
|
|
98
|
+
}
|
|
99
|
+
get timestamp() {
|
|
100
|
+
return this._timestamp;
|
|
101
|
+
}
|
|
102
|
+
get restricted() {
|
|
103
|
+
return this._restricted;
|
|
104
|
+
}
|
|
105
|
+
// ─────────────────────────────
|
|
106
|
+
// Mutators (restricted)
|
|
107
|
+
// ─────────────────────────────
|
|
108
|
+
/**
|
|
109
|
+
* Only mutable field
|
|
110
|
+
*/
|
|
111
|
+
set label(label) {
|
|
112
|
+
assertString(label, "label");
|
|
113
|
+
this._label = label;
|
|
114
|
+
}
|
|
115
|
+
// ─────────────────────────────
|
|
116
|
+
// Identity checks
|
|
117
|
+
// ─────────────────────────────
|
|
118
|
+
/**
|
|
119
|
+
* Returns true if identity is restricted
|
|
120
|
+
*/
|
|
121
|
+
isRestricted() {
|
|
122
|
+
return this._restricted === true;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Verify identity integrity
|
|
126
|
+
* Detects tampering of id/public_key
|
|
127
|
+
*/
|
|
128
|
+
validateIntegrity() {
|
|
129
|
+
const expected = sha256(`${this._userId}:${this._publicKey}:${this._id}`);
|
|
130
|
+
return expected === this._phash;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Explicit verification helper
|
|
134
|
+
*/
|
|
135
|
+
matches(userId, publicKey) {
|
|
136
|
+
assertString(userId, "userId");
|
|
137
|
+
assertString(publicKey, "publicKey");
|
|
138
|
+
const hash = sha256(`${userId}:${publicKey}:${this._id}`);
|
|
139
|
+
return hash === this._phash;
|
|
140
|
+
}
|
|
141
|
+
// ─────────────────────────────
|
|
142
|
+
// Serialization
|
|
143
|
+
// ─────────────────────────────
|
|
144
|
+
toJSON() {
|
|
145
|
+
return {
|
|
146
|
+
id: this._id,
|
|
147
|
+
user_id: this._userId,
|
|
148
|
+
public_key: this._publicKey,
|
|
149
|
+
phash: this._phash,
|
|
150
|
+
label: this._label,
|
|
151
|
+
timestamp: this._timestamp,
|
|
152
|
+
restricted: this._restricted,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
static fromJSON(json) {
|
|
156
|
+
const obj = typeof json === "string" ? JSON.parse(json) : json;
|
|
157
|
+
assert(typeof obj === "object" && obj !== null, "Invalid JSON object");
|
|
158
|
+
const identity = new MajikMessageIdentity({
|
|
159
|
+
id: obj.id,
|
|
160
|
+
userId: obj.user_id,
|
|
161
|
+
publicKey: obj.public_key,
|
|
162
|
+
phash: obj.phash,
|
|
163
|
+
label: obj.label,
|
|
164
|
+
timestamp: obj.timestamp,
|
|
165
|
+
restricted: obj.restricted,
|
|
166
|
+
});
|
|
167
|
+
assert(identity.validateIntegrity(), "Invalid phash in JSON");
|
|
168
|
+
return identity;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Target gender brackets for the audience.
|
|
3
|
+
*/
|
|
4
|
+
export declare const UserGenderOptions: {
|
|
5
|
+
readonly MALE: "Male";
|
|
6
|
+
readonly FEMALE: "Female";
|
|
7
|
+
readonly OTHER: "Other";
|
|
8
|
+
};
|
|
9
|
+
export type UserGenderOptions = (typeof UserGenderOptions)[keyof typeof UserGenderOptions];
|
|
10
|
+
/**
|
|
11
|
+
* Enum representing different types of social media platforms.
|
|
12
|
+
*/
|
|
13
|
+
export declare const SocialLinkType: {
|
|
14
|
+
readonly FACEBOOK: "Facebook";
|
|
15
|
+
readonly X: "X";
|
|
16
|
+
readonly TIKTOK: "Tik-Tok";
|
|
17
|
+
readonly THREADS: "Threads";
|
|
18
|
+
readonly INSTAGRAM: "Instagram";
|
|
19
|
+
readonly YOUTUBE: "Youtube";
|
|
20
|
+
readonly SPOTIFY: "Spotify";
|
|
21
|
+
readonly APPLE_MUSIC: "Apple Music";
|
|
22
|
+
readonly LINKEDIN: "LinkedIn";
|
|
23
|
+
readonly WEBSITE: "Website URL";
|
|
24
|
+
};
|
|
25
|
+
export type SocialLinkType = (typeof SocialLinkType)[keyof typeof SocialLinkType];
|
|
26
|
+
/** Payment methods accepted for the invoice */
|
|
27
|
+
export declare const PaymentMethod: {
|
|
28
|
+
/** Payment is made in cash */
|
|
29
|
+
readonly CASH: "Cash";
|
|
30
|
+
/** Payment is made via bank transfer or deposit */
|
|
31
|
+
readonly BANK: "Bank";
|
|
32
|
+
/** Payment is made via e-wallet transfer */
|
|
33
|
+
readonly EWALLET: "E-Wallet";
|
|
34
|
+
/** Payment is made using a check */
|
|
35
|
+
readonly CHECK: "Check";
|
|
36
|
+
};
|
|
37
|
+
export type PaymentMethod = (typeof PaymentMethod)[keyof typeof PaymentMethod];
|
|
38
|
+
export declare const Visibility: {
|
|
39
|
+
readonly PRIVATE: "Private";
|
|
40
|
+
readonly PUBLIC: "Public";
|
|
41
|
+
readonly LIMITED: "Limited";
|
|
42
|
+
readonly UNLISTED: "Unlisted";
|
|
43
|
+
};
|
|
44
|
+
export type Visibility = (typeof Visibility)[keyof typeof Visibility];
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Target gender brackets for the audience.
|
|
3
|
+
*/
|
|
4
|
+
export const UserGenderOptions = {
|
|
5
|
+
MALE: 'Male',
|
|
6
|
+
FEMALE: 'Female',
|
|
7
|
+
OTHER: 'Other'
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Enum representing different types of social media platforms.
|
|
11
|
+
*/
|
|
12
|
+
export const SocialLinkType = {
|
|
13
|
+
FACEBOOK: 'Facebook',
|
|
14
|
+
X: 'X',
|
|
15
|
+
TIKTOK: 'Tik-Tok',
|
|
16
|
+
THREADS: 'Threads',
|
|
17
|
+
INSTAGRAM: 'Instagram',
|
|
18
|
+
YOUTUBE: 'Youtube',
|
|
19
|
+
SPOTIFY: 'Spotify',
|
|
20
|
+
APPLE_MUSIC: 'Apple Music',
|
|
21
|
+
LINKEDIN: 'LinkedIn',
|
|
22
|
+
WEBSITE: 'Website URL'
|
|
23
|
+
};
|
|
24
|
+
/** Payment methods accepted for the invoice */
|
|
25
|
+
export const PaymentMethod = {
|
|
26
|
+
/** Payment is made in cash */
|
|
27
|
+
CASH: 'Cash',
|
|
28
|
+
/** Payment is made via bank transfer or deposit */
|
|
29
|
+
BANK: 'Bank',
|
|
30
|
+
/** Payment is made via e-wallet transfer */
|
|
31
|
+
EWALLET: 'E-Wallet',
|
|
32
|
+
/** Payment is made using a check */
|
|
33
|
+
CHECK: 'Check'
|
|
34
|
+
};
|
|
35
|
+
export const Visibility = {
|
|
36
|
+
PRIVATE: 'Private',
|
|
37
|
+
PUBLIC: 'Public',
|
|
38
|
+
LIMITED: 'Limited',
|
|
39
|
+
UNLISTED: 'Unlisted'
|
|
40
|
+
};
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import type { UserBasicInformation, FullName, Address, UserSettings, MajikUserJSON, SupabaseUser, YYYYMMDD } from './types';
|
|
2
|
+
import type { UserGenderOptions } from './enums';
|
|
3
|
+
export interface MajikUserData<TMetadata extends UserBasicInformation = UserBasicInformation> {
|
|
4
|
+
id: string;
|
|
5
|
+
email: string;
|
|
6
|
+
displayName: string;
|
|
7
|
+
hash: string;
|
|
8
|
+
metadata: TMetadata;
|
|
9
|
+
settings: UserSettings;
|
|
10
|
+
createdAt: Date;
|
|
11
|
+
lastUpdate: Date;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Base user class for database persistence
|
|
15
|
+
* Designed to be extended by subclasses with additional metadata
|
|
16
|
+
*/
|
|
17
|
+
export declare class MajikUser<TMetadata extends UserBasicInformation = UserBasicInformation> {
|
|
18
|
+
readonly id: string;
|
|
19
|
+
protected _email: string;
|
|
20
|
+
protected _displayName: string;
|
|
21
|
+
protected _hash: string;
|
|
22
|
+
protected _metadata: TMetadata;
|
|
23
|
+
protected _settings: UserSettings;
|
|
24
|
+
readonly createdAt: Date;
|
|
25
|
+
protected _lastUpdate: Date;
|
|
26
|
+
constructor(data: MajikUserData<TMetadata>);
|
|
27
|
+
/**
|
|
28
|
+
* Initialize a new user with email and display name
|
|
29
|
+
* Generates a UUID for the id if unset and sets timestamps
|
|
30
|
+
*/
|
|
31
|
+
static initialize<T extends MajikUser>(this: new (data: MajikUserData<any>) => T, email: string, displayName: string, id?: string): T;
|
|
32
|
+
/**
|
|
33
|
+
* Deserialize user from JSON object or JSON string
|
|
34
|
+
*/
|
|
35
|
+
static fromJSON<T extends MajikUser>(this: new (data: MajikUserData<any>) => T, json: MajikUserJSON<any> | string): T;
|
|
36
|
+
/**
|
|
37
|
+
* Create MajikUser from Supabase User object
|
|
38
|
+
* Maps Supabase user fields to MajikUser structure
|
|
39
|
+
*/
|
|
40
|
+
static fromSupabase<T extends MajikUser>(this: new (data: MajikUserData<any>) => T, supabaseUser: SupabaseUser): T;
|
|
41
|
+
get email(): string;
|
|
42
|
+
get displayName(): string;
|
|
43
|
+
get hash(): string;
|
|
44
|
+
get metadata(): Readonly<TMetadata>;
|
|
45
|
+
get settings(): Readonly<UserSettings>;
|
|
46
|
+
get lastUpdate(): Date;
|
|
47
|
+
/**
|
|
48
|
+
* Get user's full name if available
|
|
49
|
+
*/
|
|
50
|
+
get fullName(): string | null;
|
|
51
|
+
get fullNameObject(): FullName | null;
|
|
52
|
+
set fullNameObject(name: FullName);
|
|
53
|
+
/**
|
|
54
|
+
* Get user's formatted name (first + last)
|
|
55
|
+
*/
|
|
56
|
+
get formattedName(): string;
|
|
57
|
+
/**
|
|
58
|
+
* Get user's first name if available
|
|
59
|
+
*/
|
|
60
|
+
get firstName(): string | null;
|
|
61
|
+
/**
|
|
62
|
+
* Get user's last name if available
|
|
63
|
+
*/
|
|
64
|
+
get lastName(): string | null;
|
|
65
|
+
/**
|
|
66
|
+
* Get user's gender
|
|
67
|
+
*/
|
|
68
|
+
get gender(): string;
|
|
69
|
+
/**
|
|
70
|
+
* Calculate user's age from birthdate
|
|
71
|
+
*/
|
|
72
|
+
get age(): number | null;
|
|
73
|
+
/**
|
|
74
|
+
* Get user's first name if available
|
|
75
|
+
*/
|
|
76
|
+
get birthday(): YYYYMMDD | null;
|
|
77
|
+
/**
|
|
78
|
+
* Check if email is verified
|
|
79
|
+
*/
|
|
80
|
+
get isEmailVerified(): boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Check if phone is verified
|
|
83
|
+
*/
|
|
84
|
+
get isPhoneVerified(): boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Check if identity is verified
|
|
87
|
+
*/
|
|
88
|
+
get isIdentityVerified(): boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Check if all verification steps are complete
|
|
91
|
+
*/
|
|
92
|
+
get isFullyVerified(): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Get user's initials from name or display name
|
|
95
|
+
*/
|
|
96
|
+
get initials(): string;
|
|
97
|
+
set email(value: string);
|
|
98
|
+
set displayName(value: string);
|
|
99
|
+
set hash(value: string);
|
|
100
|
+
/**
|
|
101
|
+
* Update user's full name
|
|
102
|
+
*/
|
|
103
|
+
setName(name: FullName): void;
|
|
104
|
+
/**
|
|
105
|
+
* Update user's profile picture
|
|
106
|
+
*/
|
|
107
|
+
setPicture(url: string): void;
|
|
108
|
+
/**
|
|
109
|
+
* Update user's phone number
|
|
110
|
+
*/
|
|
111
|
+
setPhone(phone: string): void;
|
|
112
|
+
/**
|
|
113
|
+
* Update user's address
|
|
114
|
+
*/
|
|
115
|
+
setAddress(address: Address): void;
|
|
116
|
+
/**
|
|
117
|
+
* Update user's birthdate
|
|
118
|
+
* Accepts either YYYY-MM-DD string or Date object
|
|
119
|
+
*/
|
|
120
|
+
setBirthdate(birthdate: YYYYMMDD | Date): void;
|
|
121
|
+
/**
|
|
122
|
+
* Update user's address
|
|
123
|
+
*/
|
|
124
|
+
setGender(gender: UserGenderOptions): void;
|
|
125
|
+
/**
|
|
126
|
+
* Update user's bio
|
|
127
|
+
*/
|
|
128
|
+
setBio(bio: string): void;
|
|
129
|
+
/**
|
|
130
|
+
* Update user's language preference
|
|
131
|
+
*/
|
|
132
|
+
setLanguage(language: string): void;
|
|
133
|
+
/**
|
|
134
|
+
* Update user's timezone
|
|
135
|
+
*/
|
|
136
|
+
setTimezone(timezone: string): void;
|
|
137
|
+
/**
|
|
138
|
+
* Add or update a social link
|
|
139
|
+
*/
|
|
140
|
+
setSocialLink(platform: string, url: string): void;
|
|
141
|
+
/**
|
|
142
|
+
* Remove a social link
|
|
143
|
+
*/
|
|
144
|
+
removeSocialLink(platform: string): void;
|
|
145
|
+
/**
|
|
146
|
+
* Update a specific metadata field
|
|
147
|
+
*/
|
|
148
|
+
setMetadata(key: keyof TMetadata, value: TMetadata[typeof key]): void;
|
|
149
|
+
/**
|
|
150
|
+
* Merge multiple metadata fields
|
|
151
|
+
*/
|
|
152
|
+
updateMetadata(updates: Partial<TMetadata>): void;
|
|
153
|
+
/**
|
|
154
|
+
* Mark email as verified
|
|
155
|
+
*/
|
|
156
|
+
verifyEmail(): void;
|
|
157
|
+
/**
|
|
158
|
+
* Mark email as unverified
|
|
159
|
+
*/
|
|
160
|
+
unverifyEmail(): void;
|
|
161
|
+
/**
|
|
162
|
+
* Mark phone as verified
|
|
163
|
+
*/
|
|
164
|
+
verifyPhone(): void;
|
|
165
|
+
/**
|
|
166
|
+
* Mark phone as unverified
|
|
167
|
+
*/
|
|
168
|
+
unverifyPhone(): void;
|
|
169
|
+
/**
|
|
170
|
+
* Mark identity as verified (KYC)
|
|
171
|
+
*/
|
|
172
|
+
verifyIdentity(): void;
|
|
173
|
+
/**
|
|
174
|
+
* Mark identity as unverified
|
|
175
|
+
*/
|
|
176
|
+
unverifyIdentity(): void;
|
|
177
|
+
/**
|
|
178
|
+
* Update a specific setting
|
|
179
|
+
*/
|
|
180
|
+
setSetting(key: string, value: unknown): void;
|
|
181
|
+
/**
|
|
182
|
+
* Merge multiple settings
|
|
183
|
+
*/
|
|
184
|
+
updateSettings(updates: Partial<UserSettings>): void;
|
|
185
|
+
/**
|
|
186
|
+
* Enable notifications
|
|
187
|
+
*/
|
|
188
|
+
enableNotifications(): void;
|
|
189
|
+
/**
|
|
190
|
+
* Disable notifications
|
|
191
|
+
*/
|
|
192
|
+
disableNotifications(): void;
|
|
193
|
+
/**
|
|
194
|
+
* Check if user is currently restricted
|
|
195
|
+
*/
|
|
196
|
+
isCurrentlyRestricted(): boolean;
|
|
197
|
+
/**
|
|
198
|
+
* Restrict user until a specific date (or indefinitely)
|
|
199
|
+
*/
|
|
200
|
+
restrict(until?: Date): void;
|
|
201
|
+
/**
|
|
202
|
+
* Remove restriction from user
|
|
203
|
+
*/
|
|
204
|
+
unrestrict(): void;
|
|
205
|
+
/**
|
|
206
|
+
* Check if this user has the same ID as another user
|
|
207
|
+
*/
|
|
208
|
+
equals(other: MajikUser): boolean;
|
|
209
|
+
/**
|
|
210
|
+
* Check if user has complete profile information
|
|
211
|
+
*/
|
|
212
|
+
hasCompleteProfile(): boolean;
|
|
213
|
+
/**
|
|
214
|
+
* Get profile completion percentage (0-100)
|
|
215
|
+
*/
|
|
216
|
+
getProfileCompletionPercentage(): number;
|
|
217
|
+
validate(): {
|
|
218
|
+
isValid: boolean;
|
|
219
|
+
errors: string[];
|
|
220
|
+
};
|
|
221
|
+
/**
|
|
222
|
+
* Create a shallow clone of the user
|
|
223
|
+
*/
|
|
224
|
+
clone(): MajikUser<TMetadata>;
|
|
225
|
+
/**
|
|
226
|
+
* Get a supabase ready version of user data (metadata)
|
|
227
|
+
*/
|
|
228
|
+
toSupabaseJSON(): Record<string, unknown>;
|
|
229
|
+
/**
|
|
230
|
+
* Get a sanitized version of user data (removes sensitive info)
|
|
231
|
+
*/
|
|
232
|
+
toPublicJSON(): Record<string, unknown>;
|
|
233
|
+
/**
|
|
234
|
+
* Serialize user to JSON-compatible object
|
|
235
|
+
*/
|
|
236
|
+
toJSON(): MajikUserJSON<TMetadata>;
|
|
237
|
+
/**
|
|
238
|
+
* Updates the lastUpdate timestamp
|
|
239
|
+
*/
|
|
240
|
+
protected updateTimestamp(): void;
|
|
241
|
+
/**
|
|
242
|
+
* Validates email format
|
|
243
|
+
*/
|
|
244
|
+
protected validateEmail(email: string): void;
|
|
245
|
+
/**
|
|
246
|
+
* Generate a cryptographically secure unique identifier
|
|
247
|
+
*/
|
|
248
|
+
protected static generateID(): string;
|
|
249
|
+
/**
|
|
250
|
+
* Validate ID format
|
|
251
|
+
*/
|
|
252
|
+
protected static validateID(id: string): boolean;
|
|
253
|
+
/**
|
|
254
|
+
* Hash an ID using SHA-256
|
|
255
|
+
*/
|
|
256
|
+
protected static hashID(id: string): string;
|
|
257
|
+
}
|