How do you hand off and rename a custodial NEAR account to a user? - nearprotocol

A toy example:
The application NFTApp created a new account throwaway.near for a new user and minted some NFTs into it. NFTApp has the only full access key to throwaway.near. The user doesn't even know what a seed phrase is.
At a later time, the user decides they want to take possession of this account and its contents but name it keeper.near. Maybe they have created keeper.near previously or maybe they create it fresh as part of this process. Either way, the user controls the only full access key to keeper.near.
NFTApp then deletes throwaway.near and recovers the storage tokens from it.
How can we effect this handoff without needing to manually send contents from throwaway.near to keeper.near?

Related

A deleted testnet account gets fully restored

I'm currently playing some stuffs with Near (testnet) following an example on github/Learn-NEAR/starter--near-sdk-as.
I accidentally deleted my account - quantransedev. After that I re-created with the same account name with new passphrase of course. I noticed the newly created account had everything the old one had. It seemed like a restore account.
Is this an expected behavior? it doesn't make sense to me at all in terms of security. Please advise.
https://explorer.testnet.near.org/accounts/quantransedev.testnet
https://explorer.testnet.near.org/transactions/3GTFEzvTfDiAxm8fdpZeWP7NjRFTjFJaDYQNX6ANAUns
This is expected behavior - when you delete an account it does not delete all the things this account owns or controls. That needs to be done manually before account is deleted.
Account deletion just deletes the information about this specific account state on-chain.
When you recreate the account - it will actually be back to controlling whatever was linking to it by account id.
Generally, if you delete account - that name and things it owns are up for grubs for anyone else, so account deletion should be done very careful.
Filed two issues to improve experience here:
https://github.com/near/nearcore/issues/5816
https://github.com/near/near-cli/issues/900
The account had been deleted and the remaining funds were burnt since the beneficiary account did not exist (the account got removed before the transfer was initiated). You can also confirm that the account had actually been removed by reviewing the next transactions (deletion of other accounts with beneficiary account id set to quantransedev.testnet) did not succeed to transfer the remaining tokens from the removed accounts (the tokens got burnt).
You had had to re-create the account explicitly from scratch: https://explorer.testnet.near.org/transactions/CroKF7ipwM3fDgH5ogVrnWS6JSmnhvjkaJNDqiWzjsm2 to gain control over the account id. Before that moment, the account did not exist on the chain. Explorer, however, keeps track of all the ever-existing accounts on the network, which might have confused you.

Can a contract remove itself in NEAR Protocol?

I want to design the flow of upgrading a locked contract.
(A locked contract is the one that has no access keys allowing to alter the code; e.g. the full access key is removed once the code is deployed).
By design, there are no keys that can sign the transaction on behalf of the account to initiate the account deletion for a locked account, but I wonder if the code deployed on the account (the contract code) can still remove itself (self-destroy) [I assume it is possible since it seems that it can issue receipts from self to self].
Would the following upgrade strategy work?
Initial phase:
Create an account
Deploy code with some upgradability helpers
Lock the account (remove the full access key)
Upgrade:
Create a new account
Deploy new code to the new account
Lock the new account
Call the migration method, which reaches to the old version (via a cross-contract call) and requests to transfer the ownership (give all the data and remove itself)
It seems that some sort of owner validation will need to be implemented in the upgradability helpers to make sure that only an owner can transfer the ownership from the old version to the new one, but that is another question; first, I want to know if a contract can destroy itself.
I believe it is possible. You can have a method that uses promise_batch_action_delete_account to delete self and then add an access key to the contract that allows it to call that method.
Delete contracts or accounts using
Promise::new(contract_id).delete_account(beneficiary_id);
Reference: https://docs.rs/near-sdk/3.1.0/near_sdk/struct.Promise.html#method.delete_account
Source code: https://github.com/near/near-sdk-rs/blob/9d99077c6acfde68c06845f2a1eb2b5ed7983401/near-sdk/src/promise.rs#L309

Allow admin user to login as other users

Is there any way to login other users account for admin user ?
Currently authentication based on Meteor Accounts
I saw this post but didn't working at all now.
The feature is important for us because when user have problem in system then admin need to see it this by simulating user account.
Thanks in advance.
It seems you want to impersonate a user. This means that you want to have Meteor.userId (or this.userId depending on context) reflect the _id of a specific user both on the client and the server.
afaict the only way to do this is to login as the user. Presumably you don't want to ask the user for their password so you have a couple of choices:
Save their existing password, replace it (temporarily) with a password of your choosing, then after you're done impersonating their account, restore their existing password.
You probably don't want to ask the user for their password and you don't need to. All you need to do is set aside Meteor.user.findOne(userId).services.password.bcrypt, then reset the password to your temporary value, then restore the original bcrypt value later.
The downside is that the original user would not be able to login while you are logged-in. Plus it's really hacky.
Extend Meteor's Accounts package to provide impersonation capability in a more elegant manner.
You might also look at validateLoginAttempt. The docs are unclear as to whether a failed login attempt could be overridden with a successful one but if it could then that would provide another pathway to solve your problem.
Instead of logging in as the users, which requires their password and which is a total no-no, you may use rather alanning:roles and allow the admin to assign the role of any user in order to draw views based the user's role.
This requires a well designed role system.
As a plus you could then at least load the documents associated with the user who you want to support.
This requires a well designed document and data model.
But generally spoken you should rather focus on writing good tests (test driven development) for components as unit tests, integration tests and UI tests.
This will reduce the need to manually view the app as an end user a lot.
The most common end user problems can be reduced by creating a good knowledge base like a wiki or video tutorials.
Even if then an error occurs in the end user side, I would rather try to implement a well designed error log that allows users automatically create tickets on error which also include the error stack.
All the above methods are to be favored before logging in AS THE USER.
As #Jankpunkt has already mentioned alanning-roles I can add something you can use without installing any external package.
Just keep a type key in the profile object of the users collection. Then define some types like 1 for super-admin, 2 for admin, 3 for general etc. Then check the authorisation of particular action by checking the value of user.profile.type key.
Caveats: Make sure you are checking the type in server side. By default profile field is writable from the client end, so if you are putting type field in the profile object make sure that you are not allowing users to modify users collection in the client end.
Here is how to restrict client end update in users collection:
Meteor.users.deny({
update() { return true; }
});
Read more on roles and permissions here:
https://guide.meteor.com/accounts.html#roles-and-permissions

Restrict one current submission per device

I would like to store one user preference per iOS and android device in a database.
Ideally it would be per user but as I don't want to maintain a login system. I want to do it this way.
How can I do this?
Note first that you can use the anonymous user system to create users for you and you could look at using that. You could also create a real user with randomly generated (UUID) username and password which are then stored in the keychain.
Alternatively, use the installation which is created for each device.

How to verify requests to my Parse.com app?

I have an app that uses parse.com as backend.
If I want to store information about user's in-app purchases in table there, how can I be sure that some guy is not going to create a simple app where users of my app can log (like in my own) in and write in parse-tables whatever they want (for ex.: that they made in-apps when they really didn't). This info is used to give the user access to app's features so it's important that the user really paid for that.
Don't make the table name public knowledge, so don't ever access it directly from the app, always use cloud code. Pass the cloud code some salted hashed details to verify against, and do the verification on save of any new objects being added toot that table with a before save hook. Drop any new objects which don't pass the test.

Resources