Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions chain-api/src/client/api/PublicKeyContractAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
GetMyProfileDto,
GetPublicKeyDto,
PublicKey,
RegisterEthUserDto,
RegisterUserDto,
UpdatePublicKeyDto,
UserProfile,
Expand All @@ -30,7 +29,6 @@ export interface PublicKeyContractAPI extends CommonContractAPI {
GetPublicKey(user?: string | GetPublicKeyDto): Promise<GalaChainResponse<PublicKey>>;
UpdatePublicKey(dto: UpdatePublicKeyDto): Promise<GalaChainResponse<void>>;
RegisterUser(dto: RegisterUserDto): Promise<GalaChainResponse<string>>;
RegisterEthUser(dto: RegisterEthUserDto): Promise<GalaChainResponse<string>>;
GetMyProfile(dto: GetMyProfileDto): Promise<GalaChainResponse<UserProfile>>;
}

Expand All @@ -51,10 +49,6 @@ export const publicKeyContractAPI = (client: ChainClient): PublicKeyContractAPI
return client.submitTransaction("RegisterUser", dto) as Promise<GalaChainResponse<string>>;
},

RegisterEthUser(dto: RegisterEthUserDto) {
return client.submitTransaction("RegisterEthUser", dto) as Promise<GalaChainResponse<string>>;
},

UpdatePublicKey(dto: UpdatePublicKeyDto) {
return client.submitTransaction("UpdatePublicKey", dto) as Promise<GalaChainResponse<void>>;
},
Expand Down
15 changes: 0 additions & 15 deletions chain-api/src/types/dtos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -600,21 +600,6 @@ export class RegisterUserDto extends SubmitCallDTO {
}
}

/**
* @description
*
* Dto for secure method to save public keys for Eth users.
* Method is called and signed by Curators
*/
@JSONSchema({
description: `Dto for secure method to save public keys for Eth users. Method is called and signed by Curators`
})
export class RegisterEthUserDto extends SubmitCallDTO {
@JSONSchema({ description: "Public secp256k1 key (compact or non-compact, hex or base64)." })
@IsNotEmpty()
publicKey: string;
}

export class UpdatePublicKeyDto extends SubmitCallDTO {
@JSONSchema({
description:
Expand Down
19 changes: 19 additions & 0 deletions chain-api/src/validators/IsUserAlias.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ class TestDto extends ChainCallDTO {
user: UserAlias;
}

class TestClientDto extends ChainCallDTO {
@IsUserAlias({ clientAliasOnly: true })
user: UserAlias;
}

class TestArrayDto extends ChainCallDTO {
@IsUserAlias({ each: true })
users: UserAlias[];
Expand Down Expand Up @@ -88,6 +93,20 @@ it("should validate array of user aliases", async () => {
await expect(invalid).rejects.toThrow(`users property with values eth|${invalidChecksumEth} are not valid`);
});

it("should validate client alias only", async () => {
// Given
const validPlain = { user: "client|123" as UserAlias };
const invalidPlain = { user: "service|123" as UserAlias };

// When
const valid = await createValidDTO(TestClientDto, validPlain);
const invalid = createValidDTO(TestClientDto, invalidPlain);

// Then
expect(valid.user).toBe(validPlain.user);
await expect(invalid).rejects.toThrow(`Only string following the format of 'client|<user-id>' is allowed`);
});

it("should support schema generation", () => {
// When
const schema1 = generateSchema(TestDto);
Expand Down
27 changes: 22 additions & 5 deletions chain-api/src/validators/IsUserAlias.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,17 @@ export function isValidUserAlias(value: unknown): value is UserAlias {
return meansValidUserAlias(result);
}

function requiresClientAliasOnly(args: ValidationArguments): boolean {
return args.constraints?.[0] as boolean;
}

const customMessages = {
[UserAliasValidationResult.INVALID_ETH_USER_ALIAS]:
"User alias starting with 'eth|' must end with valid checksumed eth address without 0x prefix."
};

const clientAliasOnlyMessage = "Only string following the format of 'client|<user-id>' is allowed";

const genericMessage =
"Expected string following the format of 'client|<user-id>', or 'eth|<checksumed-eth-addr>', " +
"or valid system-level username.";
Expand All @@ -99,21 +105,32 @@ class IsUserAliasConstraint implements ValidatorConstraintInterface {
return value.every((val) => this.validate(val, args));
}
const result = validateUserAlias(value);
return meansValidUserAlias(result);

if (requiresClientAliasOnly(args)) {
return meansValidUserAlias(result) && (value as string)?.startsWith("client|");
} else {
return meansValidUserAlias(result);
}
}

defaultMessage(args: ValidationArguments): string {
const value = args.value;
const defaultMessage = requiresClientAliasOnly(args) ? clientAliasOnlyMessage : genericMessage;

if (Array.isArray(value)) {
const invalidValues = value.filter((val) => !meansValidUserAlias(validateUserAlias(val)));
return `${args.property} property with values ${invalidValues} are not valid GalaChain user aliases. ${genericMessage}`;
return `${args.property} property with values ${invalidValues} are not valid GalaChain user aliases. ${defaultMessage}`;
}
const result = validateUserAlias(args.value);
const details = customMessages[result] ?? genericMessage;
const details = customMessages[result] ?? defaultMessage;
return `${args.property} property with value ${args.value} is not a valid GalaChain user alias. ${details}`;
}
}

interface IsUserAliasOptions extends ValidationOptions {
clientAliasOnly?: boolean;
}

/**
* @description
*
Expand All @@ -127,14 +144,14 @@ class IsUserAliasConstraint implements ValidatorConstraintInterface {
* @param options
*
*/
export function IsUserAlias(options?: ValidationOptions) {
export function IsUserAlias(options?: IsUserAliasOptions) {
return function (object: object, propertyName: string) {
registerDecorator({
name: "isUserAlias",
target: object.constructor,
propertyName,
options,
constraints: [],
constraints: options?.clientAliasOnly ? [true] : [],
validator: IsUserAliasConstraint
});
};
Expand Down
12 changes: 2 additions & 10 deletions chain-cli/chaincode-template/e2e/__snapshots__/api.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -12194,9 +12194,9 @@ The key is generated by the caller and should be unique for each DTO. You can us
},
},
{
"description": "Registers a new user on chain under alias derived from eth address. Transaction updates the chain (submit). Allowed roles: REGISTRAR.",
"deprecated": true,
"description": "Registration of eth| users is no longer required. This method will be removed in the future. Transaction updates the chain (submit). Allowed roles: REGISTRAR.",
"dtoSchema": {
"description": "Dto for secure method to save public keys for Eth users. Method is called and signed by Curators",
"properties": {
"dtoExpiresAt": {
"description": "Unit timestamp when the DTO expires. If the timestamp is in the past, the DTO is not valid.",
Expand All @@ -12218,11 +12218,6 @@ The key is generated by the caller and should be unique for each DTO. You can us
"minLength": 1,
"type": "string",
},
"publicKey": {
"description": "Public secp256k1 key (compact or non-compact, hex or base64).",
"minLength": 1,
"type": "string",
},
"signature": {
"description": "Signature of the DTO signed with caller's private key to be verified with user's public key saved on chain. The 'signature' field is optional for DTO, but is required for a transaction to be executed on chain.
Please consult [GalaChain SDK documentation](https://github.com/GalaChain/sdk/blob/main/docs/authorization.md#signature-based-authorization) on how to create signatures.",
Expand All @@ -12246,9 +12241,6 @@ The key is generated by the caller and should be unique for each DTO. You can us
"type": "string",
},
},
"required": [
"publicKey",
],
"type": "object",
},
"isWrite": true,
Expand Down
4 changes: 2 additions & 2 deletions chain-cli/chaincode-template/e2e/apples.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ describe("Apple trees", () => {

beforeAll(async () => {
client = await TestClients.createForAdmin(appleContractConfig);
user = await client.createRegisteredUser();
user2 = await client.createRegisteredUser();
user = ChainUser.withRandomKeys();
user2 = ChainUser.withRandomKeys();
});

afterAll(async () => {
Expand Down
4 changes: 2 additions & 2 deletions chain-cli/chaincode-template/e2e/burnNFT.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ describe("NFT Burn scenario", () => {

beforeAll(async () => {
client = await TestClients.createForAdmin();
user1 = await client.createRegisteredUser();
user2 = await client.createRegisteredUser();
user1 = ChainUser.withRandomKeys();
user2 = ChainUser.withRandomKeys();

await mintTokensToUsers(client.assets, nftClassKey, [
{ user: user1, quantity: new BigNumber(1) },
Expand Down
15 changes: 8 additions & 7 deletions chain-cli/chaincode-template/e2e/gcclient.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ import {
GalaChainResponse,
GetMyProfileDto,
PublicKeyContractAPI,
RegisterEthUserDto,
RegisterUserDto,
UserProfile,
createValidSubmitDTO,
publicKeyContractAPI,
randomUniqueKey,
signatures
Expand Down Expand Up @@ -110,15 +111,15 @@ describeIfNonMockedChaincode("Chaincode client (CuratorOrg)", () => {

it("should register another user", async () => {
// Given
const newUser = ChainUser.withRandomKeys();
const newUser = ChainUser.withRandomKeys("new-user");

const dto = new RegisterEthUserDto();
dto.publicKey = newUser.publicKey;
dto.uniqueKey = randomUniqueKey();
dto.sign(getAdminPrivateKey(), false);
const dto = await createValidSubmitDTO(RegisterUserDto, {
user: newUser.identityKey,
publicKey: newUser.publicKey
}).signed(getAdminPrivateKey());

// When
const response = await client.RegisterEthUser(dto);
const response = await client.RegisterUser(dto);

// Then
expect(response).toEqual(GalaChainResponse.Success(newUser.identityKey));
Expand Down
8 changes: 4 additions & 4 deletions chain-cli/chaincode-template/e2e/lockNFT.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ describe("NFT lock scenario", () => {

beforeAll(async () => {
client = await TestClients.createForAdmin();
user1 = await client.createRegisteredUser();
user2 = await client.createRegisteredUser();
user1 = ChainUser.withRandomKeys();
user2 = ChainUser.withRandomKeys();

await mintTokensToUsers(client.assets, nftClassKey, [
{ user: user1, quantity: new BigNumber(2) },
Expand Down Expand Up @@ -207,8 +207,8 @@ describe("lock with allowances", () => {

beforeAll(async () => {
client = await TestClients.createForAdmin();
user1 = await client.createRegisteredUser();
user2 = await client.createRegisteredUser();
user1 = ChainUser.withRandomKeys();
user2 = ChainUser.withRandomKeys();

await mintTokensToUsers(client.assets, nftClassKey, [
{ user: user1, quantity: new BigNumber(2) },
Expand Down
4 changes: 2 additions & 2 deletions chain-cli/chaincode-template/e2e/simpleNFT.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ describe("Simple NFT scenario", () => {

beforeAll(async () => {
client = await TestClients.createForAdmin();
user1 = await client.createRegisteredUser();
user2 = await client.createRegisteredUser();
user1 = ChainUser.withRandomKeys();
user2 = ChainUser.withRandomKeys();
});

afterAll(async () => {
Expand Down
12 changes: 2 additions & 10 deletions chain-cli/chaincode-template/src/pk/__snapshots__/api.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1005,9 +1005,9 @@ The key is generated by the caller and should be unique for each DTO. You can us
},
},
{
"description": "Registers a new user on chain under alias derived from eth address. Transaction updates the chain (submit). Allowed roles: REGISTRAR.",
"deprecated": true,
"description": "Registration of eth| users is no longer required. This method will be removed in the future. Transaction updates the chain (submit). Allowed roles: REGISTRAR.",
"dtoSchema": {
"description": "Dto for secure method to save public keys for Eth users. Method is called and signed by Curators",
"properties": {
"dtoExpiresAt": {
"description": "Unit timestamp when the DTO expires. If the timestamp is in the past, the DTO is not valid.",
Expand All @@ -1029,11 +1029,6 @@ The key is generated by the caller and should be unique for each DTO. You can us
"minLength": 1,
"type": "string",
},
"publicKey": {
"description": "Public secp256k1 key (compact or non-compact, hex or base64).",
"minLength": 1,
"type": "string",
},
"signature": {
"description": "Signature of the DTO signed with caller's private key to be verified with user's public key saved on chain. The 'signature' field is optional for DTO, but is required for a transaction to be executed on chain.
Please consult [GalaChain SDK documentation](https://github.com/GalaChain/sdk/blob/main/docs/authorization.md#signature-based-authorization) on how to create signatures.",
Expand All @@ -1057,9 +1052,6 @@ The key is generated by the caller and should be unique for each DTO. You can us
"type": "string",
},
},
"required": [
"publicKey",
],
"type": "object",
},
"isWrite": true,
Expand Down
25 changes: 2 additions & 23 deletions chain-connect/src/chainApis/PublicKeyApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
GetMyProfileDto,
RegisterEthUserDto,
RegisterUserDto,
UpdatePublicKeyDto,
UserProfile
} from "@gala-chain/api";
import { GetMyProfileDto, RegisterUserDto, UpdatePublicKeyDto, UserProfile } from "@gala-chain/api";
import { plainToInstance } from "class-transformer";

import { GalaChainProvider } from "../GalaChainClient";
import { RegisterEthUserRequest, RegisterUserRequest, UpdatePublicKeyRequest } from "../types";
import { RegisterUserRequest, UpdatePublicKeyRequest } from "../types";
import { GalaChainBaseApi } from "./GalaChainBaseApi";

/**
Expand Down Expand Up @@ -73,21 +67,6 @@ export class PublicKeyApi extends GalaChainBaseApi {
});
}

/**
* Registers a new Ethereum user on the GalaChain network.
* @param dto - The Ethereum user registration request data
* @returns Promise resolving to registration confirmation
*/
public RegisterEthUser(dto: RegisterEthUserRequest) {
return this.connection.submit<string, RegisterEthUserDto>({
method: "RegisterEthUser",
payload: dto,
sign: true,
url: this.chainCodeUrl,
requestConstructor: RegisterEthUserDto
});
}

/**
* Updates the public key for the current user.
* @param dto - The public key update request data
Expand Down
5 changes: 2 additions & 3 deletions chain-connect/src/types/publicKeyApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { RegisterEthUserDto, RegisterUserDto, UpdatePublicKeyDto } from "@gala-chain/api";
import { RegisterUserDto, UpdatePublicKeyDto } from "@gala-chain/api";

import { ConstructorArgs } from "./utils";

type RegisterUserRequest = ConstructorArgs<RegisterUserDto>;
type RegisterEthUserRequest = ConstructorArgs<RegisterEthUserDto>;
type UpdatePublicKeyRequest = ConstructorArgs<UpdatePublicKeyDto>;

export { RegisterUserRequest, RegisterEthUserRequest, UpdatePublicKeyRequest };
export { RegisterUserRequest, UpdatePublicKeyRequest };
Loading
Loading