forked from Emmy123222/Stellar-MicroPay
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathusernameService.js
More file actions
138 lines (120 loc) · 3.45 KB
/
Copy pathusernameService.js
File metadata and controls
138 lines (120 loc) · 3.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* eslint-disable */
/**
* src/services/usernameService.js
* Business logic for username-to-public-key mapping and resolution.
* Uses in-memory storage for v1 (can be migrated to database later).
*/
"use strict";
// In-memory storage for username → publicKey mapping
const usernameMap = new Map();
/**
* Register a new username with a public key.
* @param {string} username - The username to register
* @param {string} publicKey - The Stellar public key
*/
function registerUsername(username, publicKey) {
validateUsername(username);
validatePublicKey(publicKey);
// Check if username already exists
if (usernameMap.has(username)) {
const error = new Error("Username already registered");
error.status = 409;
throw error;
}
// Check if public key is already registered to another username
/* eslint-disable no-unused-vars */
// eslint-disable-next-line no-unused-vars
for (const [unused, existingPublicKey] of usernameMap.entries()) { if (existingPublicKey === publicKey) {
const error = new Error("Public key already registered to another username");
error.status = 409;
throw error;
}
}
/* eslint-enable no-unused-vars */
usernameMap.set(username, publicKey);
return { username, publicKey };
}
/**
* Resolve a username to its public key.
* @param {string} username - The username to resolve
* @returns {string} The public key associated with the username
*/
function resolveUsername(username) {
validateUsername(username);
const publicKey = usernameMap.get(username);
if (!publicKey) {
const error = new Error("Username not found");
error.status = 404;
throw error;
}
return { username, publicKey };
}
/**
* Get all registered usernames (for debugging/admin purposes).
* @returns {Array} Array of { username, publicKey } objects
*/
function getAllUsernames() {
return Array.from(usernameMap.entries()).map(([username, publicKey]) => ({
username,
publicKey,
}));
}
/**
* Remove a username registration.
* @param {string} username - The username to remove
*/
function removeUsername(username) {
validateUsername(username);
if (!usernameMap.has(username)) {
const error = new Error("Username not found");
error.status = 404;
throw error;
}
usernameMap.delete(username);
return { username };
}
/**
* Validate username format.
* @param {string} username - The username to validate
*/
function validateUsername(username) {
if (!username) {
const error = new Error("Username is required");
error.status = 400;
throw error;
}
// Username must be 3-20 characters, alphanumeric, no spaces
if (!/^[a-zA-Z0-9]{3,20}$/.test(username)) {
const error = new Error(
"Username must be 3-20 characters long and contain only letters and numbers"
);
error.status = 400;
throw error;
}
}
/**
* Validate Stellar public key format.
* @param {string} publicKey - The public key to validate
*/
function validatePublicKey(publicKey) {
if (!publicKey) {
const error = new Error("Public key is required");
error.status = 400;
throw error;
}
// Stellar public keys start with 'G' and are 56 characters (G + 55 alphanumerics)
if (!/^G[A-Z0-9]{55}$/.test(publicKey)) {
const error = new Error("Invalid Stellar public key format");
error.status = 400;
throw error;
}
}
module.exports = {
registerUsername,
resolveUsername,
getAllUsernames,
removeUsername,
validateUsername,
validatePublicKey,
usernameMap,
};