Skip to content

Commit

Permalink
Added suppport for Inrupt application registration flow
Browse files Browse the repository at this point in the history
  • Loading branch information
Dexagod committed Jan 6, 2025
1 parent 8efadbc commit b28e7d5
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/authentication/CreateFetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export interface IClientCredentialsTokenAuthOptions {
logger?: Logger,
}

export interface IClientCredentialsTokenGenerationOptions {
export interface ICSSClientCredentialsTokenGenerationOptions {
name: string,
email: string,
password: string,
Expand Down
34 changes: 28 additions & 6 deletions src/authentication/TokenCreationCSS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,28 @@ import { createDpopHeader, generateDpopKeyPair } from '@inrupt/solid-client-auth

const express = require('express')

export interface IClientCredentialsTokenGenerationOptions {
export interface ICSSClientCredentialsTokenGenerationOptions {
name: string,
email: string,
password: string,
idp: string,
webId?: string,
}

export interface IInruptClientCredentialsTokenGenerationOptions {
id: string,
secret: string,
idp: string,
webId?: string,
}


export type InruptToken = {
id: string,
secret: string,
idp: string,
}

export type CSSToken = {
id: string,
secret: string,
Expand All @@ -25,11 +39,11 @@ export type CSSToken = {

import crossfetch from 'cross-fetch';

export async function generateCSSToken(options: IClientCredentialsTokenGenerationOptions) {
export async function generateCSSToken(options: ICSSClientCredentialsTokenGenerationOptions) {
return generateCSSTokenVersion7(options)
}

export async function generateCSSTokenVersion7(options: IClientCredentialsTokenGenerationOptions) {
export async function generateCSSTokenVersion7(options: ICSSClientCredentialsTokenGenerationOptions) {

if (!options.idp) throw new BashlibError(BashlibErrorMessage.noIDPOption)
if (!options.webId) throw new BashlibError(BashlibErrorMessage.noWebIDOption)
Expand Down Expand Up @@ -81,14 +95,12 @@ export async function generateCSSTokenVersion7(options: IClientCredentialsTokenG
name: options.name,
email: options.email,
idp: options.idp,


} as CSSToken

return token;
}

export async function generateCSSTokenVersion6(options: IClientCredentialsTokenGenerationOptions) {
export async function generateCSSTokenVersion6(options: ICSSClientCredentialsTokenGenerationOptions) {

if (!options.idp) throw new BashlibError(BashlibErrorMessage.noIDPOption)

Expand Down Expand Up @@ -121,3 +133,13 @@ export async function generateCSSTokenVersion6(options: IClientCredentialsTokenG

return token as CSSToken;
}


export function generateInruptToken(options: IInruptClientCredentialsTokenGenerationOptions): InruptToken {

return {
id: options.id,
secret: options.secret,
idp: options.idp
}
}
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import touch, {ICommandOptionsTouch} from "./commands/solid-touch"
import createSolidPods, {IAccountData} from "./commands/solid-pod-create"
import { listPermissions, changePermissions, deletePermissions, ICommandOptionsPermissions, IPermissionOperation, IPermissionListing, Record } from './commands/solid-perms'
import { authenticateWithTokenFromJavascript } from "./authentication/AuthenticationToken"
import { generateCSSToken, IClientCredentialsTokenGenerationOptions, CSSToken } from "./authentication/TokenCreationCSS"
import { generateCSSToken, ICSSClientCredentialsTokenGenerationOptions, CSSToken } from "./authentication/TokenCreationCSS"
import { FileInfo, ResourceInfo } from './utils/util';

// General Solid functionality
Expand All @@ -30,4 +30,4 @@ export type { Logger } from './logger';
export type { ICommandOptionsCopy, ICommandOptionsList, ICommandOptionsRemove, ICommandOptionsMove, ICommandOptionsFind, ICommandOptionsQuery, ICommandOptionsPermissions, ICommandOptionsMakeDirectory, ICommandOptionsTouch }

// Type exports
export type { IAccountData, IClientCredentialsTokenGenerationOptions, CSSToken, IPermissionOperation, FileInfo, ResourceInfo, SessionInfo, IPermissionListing, Record }
export type { IAccountData, ICSSClientCredentialsTokenGenerationOptions, CSSToken, IPermissionOperation, FileInfo, ResourceInfo, SessionInfo, IPermissionListing, Record }
81 changes: 79 additions & 2 deletions src/shell/commands/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import inquirer from 'inquirer';

import cliSelect from "cli-select"
import chalk from 'chalk';
import { generateCSSToken } from '../../authentication/TokenCreationCSS';
import { generateCSSToken, generateInruptToken } from '../../authentication/TokenCreationCSS';
import { getWebIDIdentityProvider, writeErrorString } from '../../utils/util';
import { generateDpopKeyPair } from '@inrupt/solid-client-authn-core';
import { requestAccessToken } from '../../authentication/AuthenticationToken';
Expand Down Expand Up @@ -91,7 +91,7 @@ export default class AuthCommand extends SolidCommand {
})

authcommand
.command('create-token')
.command('create-token-css')
.description('create authentication token (only for WebIDs hosted on a Community Solid Server v4.0.0 and up).')
.option('-b, --base-url <string>', 'URL of your CSS server')
.option('-n, --name <string>', 'Token name')
Expand All @@ -108,6 +108,23 @@ export default class AuthCommand extends SolidCommand {
if (this.mayExit) process.exit(0)
})


authcommand
.command('create-token-ess')
.description('Store application id and secret for authentication token generation (register bashlib here: https://login.inrupt.com/registration.html).')
.option('-b, --base-url <string>', 'URL of your Inrupt server (default is https://login.inrupt.com/)')
.option('-i, --id <string>', 'application registration id')
.option('-s, --secret <string>', 'application registration secret')
.option('-v, --verbose', 'Log actions')
.action(async (options) => {
try {
await createAuthenticationTokenInrupt(options)
} catch (e) {
writeErrorString('Could not create authentication token', e, options)
if (this.mayExit) process.exit(1)
}
if (this.mayExit) process.exit(0)
})
return program
}
}
Expand Down Expand Up @@ -299,6 +316,66 @@ async function createAuthenticationTokenCSS(options: any) {
}
}

async function createAuthenticationTokenInrupt(options: any){
options.name = options.name || "Solid-cli token"
let questions = []

let currentWebID = getConfigCurrentWebID();
let createTokenForCurrentWebID = false;
if (currentWebID) {
console.log(`Do you want to create an authentication token for ${currentWebID}? [Y/n] `);
createTokenForCurrentWebID = await new Promise((resolve, reject) => {
process.stdin.setRawMode(true);
process.stdin.resume();
process.stdin.on('data', (chk) => {
if (chk.toString('utf8') === "n") {
resolve(false);
} else {
resolve(true);
}
});
});
}

if (createTokenForCurrentWebID) {
let session = getConfigCurrentSession()
let token = getConfigCurrentToken()
let webId = getConfigCurrentWebID()
if(webId) options.webId = webId;
if (!options.baseUrl && webId) {
options.baseUrl = session?.idp || token?.idp || await getWebIDIdentityProvider(webId)
}
}

if (!options.baseUrl) questions.push({ type: 'input', name: 'baseUrl', message: 'Solid server URI', default: "https://login.inrupt.com/"})
if (!options.email) questions.push({ type: 'input', name: 'id', message: 'id'})
if (!options.password) questions.push({ type: 'input', name: 'secret', message: 'secret'})

if (questions.length) {
let answers = await inquirer.prompt(questions)
options = { ...options, ...answers }
}
options.idp = options.baseUrl;


try {
let token = await generateInruptToken(options);

// Get token WebID by creating an access token (a bit wastefull but no other option sadly)
if (!token.id || !token.secret) throw new Error('Could not create valid authentication token.')

const dpopKey = await generateDpopKeyPair();
let { accessToken, expirationDate, webId } = await requestAccessToken(token.id, token.secret, dpopKey, options);

if (!webId) throw new Error('Could not create valid authentication token.')
setConfigToken(webId, token)
console.log(`Successfully created new token ${options.name}`)
} catch (e) {
console.error(`Could not create token: ${(e as Error).message}`)
console.error(`Please make sure the filled in email and password values are correct!`)
}
}


async function setAuthenticationOption_backup(options: any) {
let webId = options.webid
Expand Down
5 changes: 3 additions & 2 deletions src/utils/configoptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ export type IAuthInfoEntry = {
}

export type ITokenEntry = {
name: string,
email: string,
name?: string,
email?: string,
idp: string,
webId: string,
id: string,
secret?: string,
}

export type ISessionEntry = {
Expand Down

0 comments on commit b28e7d5

Please sign in to comment.