Radiks and authentication

#1

I am trying to use radisk but authentication part is giving me error while following the docs, someone please point me to the right direction or give me some example snippet

#2

Your question is not entirely informative. For the last couple of days I have been introducing radiks into my application and using the available information in the radiks and radiks-server repositories I managed to get a working solution. Provide more information, I will try to help you.

#3

I am not exactly able to get how authentication should work
Can you please share snippet of authentication part

#4

If you are only interested in blockstack authentication (this is not related to radiks), then blockstack has an application generator - https://github.com/blockstack/blockstack-app-generator

All you need to add to the authentication process is

import { User, getConfig } from 'radiks';

// I use a similar code in the factory to replace userSession
const appConfig = new AppConfig(['store_write', 'publish_data']);
const _userSession = new UserSession({ appConfig });
configure({
    apiServer: window.location.origin,
    userSession: _userSession
});
const { userSession } = getConfig();

...

const handleSignIn = () => {
  if (userSession.isSignInPending()) {
    await userSession.handlePendingSignIn();
    await User.createWithCurrentUser(); // <-- this line
  }
}

Provide a sandbox with your application and we will make it working together.

#5

As you suggested i used this

const { userSession } = getConfig();
const appConfig = new AppConfig([‘store_write’, ‘publish_data’]);
const _userSession = new UserSession({
appConfig: new AppConfig([‘store_write’, ‘publish_data’])
})

configure({
  apiServer: 'window.location.origin,',
  _userSession
});
if (userSession.isSignInPending()) {
  await userSession.handlePendingSignIn();
  await User.createWithCurrentUser(); // <-- this line
}

I am getting this

Unhandled Rejection (TypeError): Cannot read property ‘isSignInPending’ of null

I am not exactly working on application, at the moment i am just trying it out

#6

check the use of _userSession vs. userSession

#7

Alright, i got past that but after following the docs i am now getting

Unhandled Rejection (TypeError): First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.

When I am trying to write something

const person = new Person({
name: ‘Hank’,
isHuman: false,
likesDogs: false // just an example, I love dogs!
})
const newAttributes = {
likesDogs: false,
age: 30
}
await person.save();
const dogHaters = await Person.fetchList({ likesDogs: false });
console.log(dogHaters)

#8

I also came across a similar error. If there is any change in the authentication component, log out and sign in again. At the moment, your code still uses the original UserSession.

I’m afraid to confuse you with my code, but I risk putting the file from my application, I hope it will be useful to someone

// AuthContext.jsx
import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
import { UserSession, AppConfig, Person } from 'blockstack';
import { configure, User, getConfig } from 'radiks';
import { useDispatch } from 'react-redux';
import { Spinner } from 'evergreen-ui';
import avatarPlaceholder from '../assets/avatar-placeholder.svg';
import { addMessage, setUserPublicKey } from '../actionCreators';

const appConfig = new AppConfig(['store_write', 'publish_data']);
const _userSession = new UserSession({ appConfig });
configure({
    apiServer: window.location.origin,
    userSession: _userSession
});
const { userSession } = getConfig();

export const AuthContext = createContext({ userSession });
const initialUserData = {};
const initialPerson = {
    name() {
        return 'Anonymous';
    },
    avatarUrl() {
        return avatarPlaceholder;
    }
};

export default function AuthProvider(props) {
    const [userData, setUserData] = useState(initialUserData);
    const [person, setPerson] = useState(initialPerson);
    const [username, setUsername] = useState(null);
    const dispatch = useDispatch();

    const isPending = userSession.isSignInPending(),
        isUserSignedIn = userSession.isUserSignedIn();

    useEffect(() => {
        if (isUserSignedIn) {
            const data = userSession.loadUserData();
            const personInstance = new Person(data.profile);
            setPerson(personInstance);
            setUsername(data.username);
        }
    }, [isUserSignedIn, dispatch]);

    const login = (event) => {
        event.preventDefault();
        userSession.redirectToSignIn(`${window.location.origin}/drive`);
    };

    const logout = (event) => {
        event.preventDefault();
        userSession.signUserOut();
    };

    if (isPending && !isUserSignedIn) {
        userSession.handlePendingSignIn().then(data => {
            setUserData(data);
            dispatch(setUserPublicKey(userSession, data.appPrivateKey));
            User.createWithCurrentUser();
        }, (e) => {
            dispatch(addMessage('auth_error', e.message, 'error'));
            window.location.replace(window.location.origin);
        });
    }

    const userDataValue = useMemo(() => ({
        userSession, userData, person, username, login, logout
    }), [userData, person, username]);

    return (
        <AuthContext.Provider value={userDataValue}>
            { isPending && !isUserSignedIn ? <Spinner /> : props.children }
        </AuthContext.Provider>
    );
}

export const useAuthContext = () => useContext(AuthContext);

// App.jsx
// imports section
import AuthProvider, { useAuthContext } from '../context/AuthContext';
// ....

function App() {
    const { userSession } = useAuthContext();

    return (
        <AuthProvider>
            {* children is your main component *}
        </AuthProvider>
    );
}

You can read about using context in the React documentation https://reactjs.org/docs/context.html