GithubHelp home page GithubHelp logo

dawe35 / skyid Goto Github PK

View Code? Open in Web Editor NEW
39.0 3.0 10.0 7.4 MB

Global frontend-only verification system for web3 dapps

Home Page: https://sky-id.hns.siasky.net/

License: MIT License

JavaScript 96.27% Python 3.73%
decentralization decentralized-applications authentication web3-dapp dapp dapps web3 skynet sia web3-dapps verification

skyid's Introduction

SkyID

Global frontend-only verification system for web3 dapps.

Demo dapp using SkyID login: https://sky-note.hns.siasky.net/

Read security logs in CHANGELOG.md

Getting started

Install

Just copy this code to your HTML:

<script>
// get portal url from response header
fetch("", {method: 'HEAD'})
.then( response => response.headers)
.then( headers => {
	let portal = headers.get('skynet-portal-api');
	let devMode = false;
	if (!portal){
		// if no header, default to siasky.net
		portal = "https://siasky.net"
		devMode = true;
	}

	let portalNoProtocol = portal.replace(/^https?\:\/\//i, "");

	// path for sky-id, easier than subdomain logic
	let path = 'https://sky-id.hns.' + portalNoProtocol;

	// create script tag
	var script = document.createElement('script');
	script.type = 'text/javascript';
	script.src = path+"/skyid.js";
	script.onload = ()=>{initSkyID(path, devMode)}; //once loaded, call method to run code that relies on it
	document.head.appendChild(script);

});

var initSkyID = function(path){
	var skyid = new SkyID('App Name', null, {customSkyidUrl:path});
}
</script>

Initialize with options and callback (optional)

// detect if app is opened on localhost for development
if (window.location.hostname == 'idtest.local' || window.location.hostname == 'localhost' || window.location.protocol == 'file:') {
	var devMode = true
} else {
	var devMode = false
}

var opts = { 'devMode': devMode  }
var skyid = new SkyID('App name', skyidEventCallback, opts)

function skyidEventCallback(message) {
	switch (message) {
		case 'login_fail':
			console.log('Login failed')
			break;
		case 'login_success':
			console.log('Login succeeded!')
			fetchNote()
			break;
		case 'destroy':
			console.log('Logout succeeded!')
			break;
		default:
			console.log(message)
			break;
	}
}

Available options:

Option default
devMode false
disableLoadingScreen false
customSkyidUrl null
onUploadProgress null

Start session (login)

skyid.sessionStart()

Destroy session (logout)

skyid.sessionDestroy()

Display classes

If you want, you can use special HTML classes, so you don't need to listen to SkyID callbacks.

  • show-if-logged-in - Set display to '' if user logged in

  • hide-if-logged-in - Set display to none if user logged in

  • show-if-initialized - Set display to '' if SkyID initialized

  • hide-if-initialized - Set display to none if SkyID initialized

Example:

<div class="show-if-logged-in"> You are logged in! </div>

You can also combine these classes:

<div class="hide-if-initialized">Loading...</div>

<div class="show-if-initialized hide-if-logged-in" style="display:none"> Loaded and you are not logged in :( </div>

<div class="show-if-initialized show-if-logged-in" style="display:none"> Loaded and you are logged in! </div>

It is important to use style="display:none" and not a CSS class the display property (bad example class="display-none") because SkyID will only reset the display attribute and not the CSS class

Documentation

Save JSON

SkyID uses SkyDB under the hood to save, modify, and fetch files. The only difference is that you don't need to remember for your secret key - SkyID generates deterministic keypairs instead.

let yourObject = { key1: 'value1' }
skyid.setJSON('filename', yourObject, function(response) {
	if (response != true) {
		alert('Sorry, skyid.setFile failed :(')
	}
})

You can store any JSON data, for example notes, settings, or a list of your uploaded files.

Get JSON

skyid.getJSON('filename', function(response) {
	if (response == false) {
		alert('Sorry, skyid.getFile failed :(')
	}
	console.log(response)
})

Set registry entry

skyid.setRegistry('filename', 'IADUs8d9CQjUO34LmdaaNPK_STuZo24rpKVfYW3wPPM2uQ', function(success) {
	if (success == false) {
		alert('Sorry, skyid.setRegistry failed :(')
	}
})

Get registry entry

skyid.getRegistry('filename', function(entry) {
	if (entry == false) {
		alert('Sorry, skyid.getRegistry failed :(')
	}
	console.log(entry)
})

Get registry URL

skydbFile = skyid.getRegistryUrl('filename')

Upload directory

<input id="my_input" type="file" multiple="" webkitdirectory="true">
let files = document.getElementById['my_input'].files
skyid.uploadDirectory(files, function(skylink) {
	console.log('File uploaded:', skylink)
})

Upload encrypted file

let file = document.getElementById['my_input'].files[0]
skyid.uploadEncryptedFile(file, 'derivationPath', function(skylink) {
	console.log('Uploaded:', skylink)
})

derivationPath can be any string. It will be hashed with the user's app-seed, no need to make it long since the app-seed is not public. It is recommended to use unique derivationPath to each file, so users can share decription keys for one file without revealing the other files

You can put a callback function to the onUploadProgress option both for upload and download.

Download encrypted file

let skylink = 'sia:/...'
skyid.downloadEncryptedFile(skylink, 'derivationPath', function(blobUrl){
	console.log('File downloaded', blobUrl)
})

RFC: https://forum.sia.tech/t/discussion-about-sky-id/64

Used libraries:

Skynet-js Sia-js

Contributors:

@Delivator

❤ Thank you! ❤

Brainstorm participants & helpers:

Taek, wkibbler, redsolver, Nemo, pjbrone, kreelud, Mortal-Killer, RBZL

Development

Install development dependencies

cd SkyID

npm install

Compiling Javascript

You need to compile your node-js files (from the src folder) to a web-browser friendly javascript. Type

npx webpack

You'll see 3 new .js file in the dist folder. If you want to edit javascript, you can make changes inside the src folder and run npx webpack again. (Of course you can use npx webpack --watch so it will watch and compile automatically if you change something.

Open in browser

You can just open the /dist/index.html in your browser.

If you're using the file:// protocol (or idtest.local as localhost domain), SkyID will recognise you're in development mode and siasky.net will be used as default Skynet portal.

Chrome won't save cookies with file:// protocol. You can use Firefox, use idtest.local as localhost domain, or upload the dist folder to Skynet.

Testing with example dapp

We have a SkyID-example-note-dapp, so you can clone it. Don't forget to change the source of skyid.js if you want to test with self-hosted SkyID (open image)

To be able to test cross-domain things, you need to setup two local virtual-host domains. If you have Wamp.NET installed (what I really recommend), this will be easy. You just need to create two sites pointing to your local SkyID projects: idtest.local for SkyID and skynote.local for the example dapp (open image).

skyid's People

Contributors

dawe35 avatar delivator avatar harej avatar mike76-dev avatar mrcnski avatar redsolver avatar vbylen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

skyid's Issues

Request: Standardize account data format

I'm possibly planning on reimplementing the Skynet API and SkyID in Rust for use in other applications in the near future and it would be helpful to make the SkyID account format clearly specified in order to aid interoperability. Also planning in the future for what kinds of information a user would need to embed in their account for use with other applications is very useful.

This might be a bit out of scope, but it might be worthwhile to consider shipping SkyID as a browser extension that provides a permissioned interface for webapps to interface with and have more fine-grained access like Metamask. I'm not a webdev so I'm not an expert on what would be involved in this.

Also it would be helpful to reconsider if JSON is the best format to use given that the bulk of the data is keys and encoding to base64 is maybe wasteful? I'm a fan of using msgpack for these kinds of things.

Seed stored in local storage when I check Remember me

Screenshot 2020-11-26 at 12 34 15

I noticed that when I use the Remember me checkbox, my seed is stored in local storage. Please consider changing it because it is like saving the password in a way that I can clearly see it. Or maybe display a tip/alert when I select Remember me that will inform about the fact that the seed is stored cleary in local storage.

SkyID central

Sky-ID central, Twitter login, HNS ownership verify

New user registration seems to be broken

Hello,

I am trying to sign up at sky-id.hns.siasky.net, and I'm consistently getting an error when submitting the new user registration. I click "sign up" and copy the passphrase, type a username in and click "Sign up"

Once I click Sign up, I get a popup saying "Failed to save file, please retry." followed by one that says "Error: unable to save profile.json" and then the page just stays there with a spinner saying "Initializing profile...."

The network console in the browser shows a 405 doing an xhr post for skyfile, with the message "Method Not Allowed" and the js console shows the following:

VM2024:1 POST https://sky-id.hns.siasky.net/skynet/skyfile 405
(anonymous) @ VM2024:1
(anonymous) @ skyid.js:1
e.exports @ skyid.js:1
e.exports @ skyid.js:1
Promise.then (async)
c.request @ skyid.js:1
(anonymous) @ skyid.js:1
e.executeRequest @ skyid.js:17
(anonymous) @ skyid.js:17
(anonymous) @ skyid.js:17
(anonymous) @ skyid.js:17
(anonymous) @ skyid.js:17
r @ skyid.js:17
t.uploadFileRequest @ skyid.js:17
(anonymous) @ skyid.js:17
(anonymous) @ skyid.js:17
(anonymous) @ skyid.js:17
(anonymous) @ skyid.js:17
r @ skyid.js:17
t.setJSON @ skyid.js:17
setJSON @ skyid.js:23
setFile @ skyid.js:23
(anonymous) @ (index):384
setMnemonic @ skyid.js:23
createAccount @ (index):379
(anonymous) @ (index):359
dispatch @ jquery.min.js:2
v.handle @ jquery.min.js:2
skyid.js:23 Error: Request failed with status code 405
    at e.exports (skyid.js:1)
    at e.exports (skyid.js:1)
    at XMLHttpRequest.d.onreadystatechange (skyid.js:1)

Thanks for your help!

biometric login (and device registration)

Having to copy the long list of words is clearly not ideal, but we also don't want to let users choose weak passwords. So instead, lets use Webauthn and FIDO.

  • Create a nonce and store it in the browser (there is a browser credential API).
  • Sign the nonce with the browser's WebAuthn ( https://webauthn.io/ ) functionality and use the signature generated from that as the seed for the private key.

What that lets you do is sign in with your biometrics (touchbar, touchid, faceid, etc) or whatever the platform supports (all major browsers now support webauthn). Still show the words as a backup phrase (like normal crypto). \

Device Auth:
Basically: "It looks like you aren't signed in on this device... enter the following code on your logged in device" kinda thing (maybe a QR code too).

stay logged in on your phones browser and scan the code for instant access

skynet offers nicities that make this pretty easy where in trad-web you'd have to setup a bunch of infrastructure. Because both sides of the new device and the old device can know known keys to look for.

QR code login to dapps

User opens SkyID on desktop, enter the app name
SkyID generates a QR code what contains the app-seed
user scans it with app

Seed-namespaces

Ability to give access to App2 to read some data of App1 without reading all App1 data.

Social logins

Is it possible to get master-seed from Google, Facebook, Github?

QR code when dapp-login

Redsolver: "Another important thing is a login flow for mobile apps. I would recommend having a QR code in the Sky ID web ui which can be scanned with the phone"

User opens SkyID on desktop, enter the app name
SkyID generates a QR code what contains the app-seed
user scans it with app

Redirect to skapp container not working as desired

If the skapp url is given in the form https://siasky.net/skylink (e.g. as produced by siasky.net web interface), then skyid.sessionStart() changes window.location.href and the web page is reloaded. After that, skyid.sessionStart() execution stops and no code is executed after that.
However, there is a short delay before the page is reloaded. Within that time, it is possible to see an error message in the console saying: "TypeError: Cannot read property 'focus' of null". Most probably, this is thrown in popupCenter() where newWindow object is undefined. (This is just an observation, which is probably not 100% related to the issue).
When the page reloads, no message is broadcast, and the app has no chance to know what has happened, so the login just fails for no obvious reason.
The second time, from the redirected url, everything works.

appId vs domains

the example is confusing me because it named itself 'example-skapp' instead of 'skyacc'
also, it should talk about domains rather than the application itself
the text should probably read
"skyacc is requesting access to the domain 'example-domain', do you wish to give it access?"
and then probably a '?' button somewhere that explains what domains are and why apps need permissions to them and what the potential consequences are of giving permissions to a bad guy
maybe some text like
"Skynet applications can request access to different domains. If you give an application access to a domain, it can overwrite any data inside of the domain. This means a malicious app can potentially delete your data if you grant it permission. Applications can only access the domains you grant them access to. So for example, a note taking app might request access to the domain "notes". A different app which requests access to the "videos" domain will not be able to modify any of the data in the "notes" domain."

Promisify SkyID functions

Make skyid functions promise compatible so we can use

return skyid.getJSON().then(...)

OR

await skyid.setJSON()

Ability to disable loading screen

Each time the skyid.setFile and skyid.getFile functions are called the screen freezes with a loading indicator.

A more elegant solution is desireable.

image

getRegistry: allow specifying a different public key

The function signature of getRegistry only allows you to specify a datakey, with the public key derived from the user's seed. Let's say I want to look up data uploaded by another user (and therefore a different pubkey). I would like to be able to look up registry data associated with a different public key.

Scopes instead of "skapps"

I think a good way to achieve this is to split it into different "sub-accounts" or "scopes" of a SkyID identity.
SkyID: Contains your profile picture, other information and all of the other ids of the sub-accounts you're using for each "scope"
skysocial?: Contains your social graph (followers, following, ...)
skyspaces: Contains your personal or public file storage data
skyfeed: Contains skyfeed-related data like posts, comments, reposts, reactions, ...
skylive: Livestreams
skymessage: Chat messages
And then a skapp could for example request access to skysocial and skyspaces to load SkySpaces-related data and combine it with the social data from skysocial
SkyFeed would request skysocial, skyfeed and skymessage in this example

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.