mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-13 21:40:45 +00:00
test: add verify email and password change required
This commit is contained in:
@@ -1,166 +1,166 @@
|
||||
import {Authenticator} from "@otplib/core";
|
||||
import {createDigest, createRandomBytes} from "@otplib/plugin-crypto";
|
||||
import {keyDecoder, keyEncoder} from "@otplib/plugin-thirty-two"; // use your chosen base32 plugin
|
||||
import { Authenticator } from "@otplib/core";
|
||||
import { createDigest, createRandomBytes } from "@otplib/plugin-crypto";
|
||||
import { keyDecoder, keyEncoder } from "@otplib/plugin-thirty-two"; // use your chosen base32 plugin
|
||||
import axios from "axios";
|
||||
import {OtpType, userProps} from "./user";
|
||||
import { OtpType, userProps } from "./user";
|
||||
|
||||
export async function addUser(props: userProps) {
|
||||
const body = {
|
||||
username: props.email,
|
||||
organization: {
|
||||
orgId: props.organization,
|
||||
},
|
||||
profile: {
|
||||
givenName: props.firstName,
|
||||
familyName: props.lastName,
|
||||
},
|
||||
email: {
|
||||
email: props.email,
|
||||
isVerified: true,
|
||||
},
|
||||
phone: {
|
||||
phone: props.phone,
|
||||
isVerified: true,
|
||||
},
|
||||
password: {
|
||||
password: props.password,
|
||||
changeRequired: props.passwordChangeRequired ?? false,
|
||||
},
|
||||
};
|
||||
if (!props.isEmailVerified) {
|
||||
delete body.email.isVerified;
|
||||
}
|
||||
if (!props.isPhoneVerified) {
|
||||
delete body.phone.isVerified;
|
||||
}
|
||||
const body = {
|
||||
username: props.email,
|
||||
organization: {
|
||||
orgId: props.organization,
|
||||
},
|
||||
profile: {
|
||||
givenName: props.firstName,
|
||||
familyName: props.lastName,
|
||||
},
|
||||
email: {
|
||||
email: props.email,
|
||||
isVerified: true,
|
||||
},
|
||||
phone: {
|
||||
phone: props.phone,
|
||||
isVerified: true,
|
||||
},
|
||||
password: {
|
||||
password: props.password,
|
||||
changeRequired: props.passwordChangeRequired ?? false,
|
||||
},
|
||||
};
|
||||
if (!props.isEmailVerified) {
|
||||
delete body.email.isVerified;
|
||||
}
|
||||
if (!props.isPhoneVerified) {
|
||||
delete body.phone.isVerified;
|
||||
}
|
||||
|
||||
return await listCall(`${process.env.ZITADEL_API_URL}/v2/users/human`, body);
|
||||
return await listCall(`${process.env.ZITADEL_API_URL}/v2/users/human`, body);
|
||||
}
|
||||
|
||||
export async function removeUserByUsername(username: string) {
|
||||
const resp = await getUserByUsername(username);
|
||||
if (!resp || !resp.result || !resp.result[0]) {
|
||||
return;
|
||||
}
|
||||
await removeUser(resp.result[0].userId);
|
||||
const resp = await getUserByUsername(username);
|
||||
if (!resp || !resp.result || !resp.result[0]) {
|
||||
return;
|
||||
}
|
||||
await removeUser(resp.result[0].userId);
|
||||
}
|
||||
|
||||
export async function removeUser(id: string) {
|
||||
await deleteCall(`${process.env.ZITADEL_API_URL}/v2/users/${id}`);
|
||||
await deleteCall(`${process.env.ZITADEL_API_URL}/v2/users/${id}`);
|
||||
}
|
||||
|
||||
async function deleteCall(url: string) {
|
||||
try {
|
||||
const response = await axios.delete(url, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.ZITADEL_SERVICE_USER_TOKEN}`,
|
||||
},
|
||||
});
|
||||
try {
|
||||
const response = await axios.delete(url, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.ZITADEL_SERVICE_USER_TOKEN}`,
|
||||
},
|
||||
});
|
||||
|
||||
if (response.status >= 400 && response.status !== 404) {
|
||||
const error = `HTTP Error: ${response.status} - ${response.statusText}`;
|
||||
console.error(error);
|
||||
throw new Error(error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error making request:", error);
|
||||
throw error;
|
||||
if (response.status >= 400 && response.status !== 404) {
|
||||
const error = `HTTP Error: ${response.status} - ${response.statusText}`;
|
||||
console.error(error);
|
||||
throw new Error(error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error making request:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getUserByUsername(username: string): Promise<any> {
|
||||
const listUsersBody = {
|
||||
queries: [
|
||||
{
|
||||
userNameQuery: {
|
||||
userName: username,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
const listUsersBody = {
|
||||
queries: [
|
||||
{
|
||||
userNameQuery: {
|
||||
userName: username,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
return await listCall(`${process.env.ZITADEL_API_URL}/v2/users`, listUsersBody);
|
||||
return await listCall(`${process.env.ZITADEL_API_URL}/v2/users`, listUsersBody);
|
||||
}
|
||||
|
||||
async function listCall(url: string, data: any): Promise<any> {
|
||||
try {
|
||||
const response = await axios.post(url, data, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${process.env.ZITADEL_SERVICE_USER_TOKEN}`,
|
||||
},
|
||||
});
|
||||
try {
|
||||
const response = await axios.post(url, data, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${process.env.ZITADEL_SERVICE_USER_TOKEN}`,
|
||||
},
|
||||
});
|
||||
|
||||
if (response.status >= 400) {
|
||||
const error = `HTTP Error: ${response.status} - ${response.statusText}`;
|
||||
console.error(error);
|
||||
throw new Error(error);
|
||||
}
|
||||
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error("Error making request:", error);
|
||||
throw error;
|
||||
if (response.status >= 400) {
|
||||
const error = `HTTP Error: ${response.status} - ${response.statusText}`;
|
||||
console.error(error);
|
||||
throw new Error(error);
|
||||
}
|
||||
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error("Error making request:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function activateOTP(userId: string, type: OtpType) {
|
||||
let url = "otp_";
|
||||
switch (type) {
|
||||
case OtpType.sms:
|
||||
url = url + "sms";
|
||||
break;
|
||||
case OtpType.email:
|
||||
url = url + "email";
|
||||
break;
|
||||
}
|
||||
let url = "otp_";
|
||||
switch (type) {
|
||||
case OtpType.sms:
|
||||
url = url + "sms";
|
||||
break;
|
||||
case OtpType.email:
|
||||
url = url + "email";
|
||||
break;
|
||||
}
|
||||
|
||||
await pushCall(`${process.env.ZITADEL_API_URL}/v2/users/${userId}/${url}`, {});
|
||||
await pushCall(`${process.env.ZITADEL_API_URL}/v2/users/${userId}/${url}`, {});
|
||||
}
|
||||
|
||||
async function pushCall(url: string, data: any) {
|
||||
try {
|
||||
const response = await axios.post(url, data, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${process.env.ZITADEL_SERVICE_USER_TOKEN}`,
|
||||
},
|
||||
});
|
||||
try {
|
||||
const response = await axios.post(url, data, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${process.env.ZITADEL_SERVICE_USER_TOKEN}`,
|
||||
},
|
||||
});
|
||||
|
||||
if (response.status >= 400) {
|
||||
const error = `HTTP Error: ${response.status} - ${response.statusText}`;
|
||||
console.error(error);
|
||||
throw new Error(error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error making request:", error);
|
||||
throw error;
|
||||
if (response.status >= 400) {
|
||||
const error = `HTTP Error: ${response.status} - ${response.statusText}`;
|
||||
console.error(error);
|
||||
throw new Error(error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error making request:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function addTOTP(userId: string): Promise<string> {
|
||||
const response = await listCall(`${process.env.ZITADEL_API_URL}/v2/users/${userId}/totp`, {});
|
||||
const code = totp(response.secret);
|
||||
await pushCall(`${process.env.ZITADEL_API_URL}/v2/users/${userId}/totp/verify`, {code: code});
|
||||
return response.secret;
|
||||
const response = await listCall(`${process.env.ZITADEL_API_URL}/v2/users/${userId}/totp`, {});
|
||||
const code = totp(response.secret);
|
||||
await pushCall(`${process.env.ZITADEL_API_URL}/v2/users/${userId}/totp/verify`, { code: code });
|
||||
return response.secret;
|
||||
}
|
||||
|
||||
export function totp(secret: string) {
|
||||
const authenticator = new Authenticator({
|
||||
createDigest,
|
||||
createRandomBytes,
|
||||
keyDecoder,
|
||||
keyEncoder,
|
||||
});
|
||||
// google authenticator usage
|
||||
const token = authenticator.generate(secret);
|
||||
const authenticator = new Authenticator({
|
||||
createDigest,
|
||||
createRandomBytes,
|
||||
keyDecoder,
|
||||
keyEncoder,
|
||||
});
|
||||
// google authenticator usage
|
||||
const token = authenticator.generate(secret);
|
||||
|
||||
// check if token can be used
|
||||
if (!authenticator.verify({token: token, secret: secret})) {
|
||||
const error = `Generated token could not be verified`;
|
||||
console.error(error);
|
||||
throw new Error(error);
|
||||
}
|
||||
// check if token can be used
|
||||
if (!authenticator.verify({ token: token, secret: secret })) {
|
||||
const error = `Generated token could not be verified`;
|
||||
console.error(error);
|
||||
throw new Error(error);
|
||||
}
|
||||
|
||||
return token;
|
||||
return token;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user