Skip to content

support to access token #233

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
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
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sqlitecloud/drivers",
"version": "1.0.438",
"version": "1.0.491",
"description": "SQLiteCloud drivers for Typescript/Javascript in edge, web and node clients",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
Expand Down
2 changes: 2 additions & 0 deletions src/drivers/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export interface SQLiteCloudConfig {
password_hashed?: boolean
/** API key can be provided instead of username and password */
apikey?: string
/** Access Token provided in place of API Key or username/password */
token?: string

/** Host name is required unless connectionstring is provided, eg: xxx.sqlitecloud.io */
host?: string
Expand Down
47 changes: 27 additions & 20 deletions src/drivers/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@
// utilities.ts - utility methods to manipulate SQL statements
//

import { SQLiteCloudConfig, SQLiteCloudError, SQLiteCloudDataTypes, DEFAULT_PORT, DEFAULT_TIMEOUT } from './types'
import { SQLiteCloudArrayType } from './types'
import { DEFAULT_PORT, DEFAULT_TIMEOUT, SQLiteCloudArrayType, SQLiteCloudConfig, SQLiteCloudDataTypes, SQLiteCloudError } from './types'

// explicitly importing these libraries to allow cross-platform support by replacing them
import { URL } from 'whatwg-url'
import { Buffer } from 'buffer'

//
// determining running environment, thanks to browser-or-node
Expand Down Expand Up @@ -42,45 +40,47 @@ export function anonimizeError(error: Error): Error {
export function getInitializationCommands(config: SQLiteCloudConfig): string {
// we check the credentials using non linearizable so we're quicker
// then we bring back linearizability unless specified otherwise
let commands = 'SET CLIENT KEY NONLINEARIZABLE TO 1; '
let commands = 'SET CLIENT KEY NONLINEARIZABLE TO 1;'

// first user authentication, then all other commands
if (config.apikey) {
commands += `AUTH APIKEY ${config.apikey}; `
commands += `AUTH APIKEY ${config.apikey};`
} else if (config.token) {
commands += `AUTH TOKEN ${config.token};`
} else {
commands += `AUTH USER ${config.username || ''} ${config.password_hashed ? 'HASH' : 'PASSWORD'} ${config.password || ''}; `
commands += `AUTH USER ${config.username || ''} ${config.password_hashed ? 'HASH' : 'PASSWORD'} ${config.password || ''};`
}

if (config.compression) {
commands += 'SET CLIENT KEY COMPRESSION TO 1; '
commands += 'SET CLIENT KEY COMPRESSION TO 1;'
}
if (config.zerotext) {
commands += 'SET CLIENT KEY ZEROTEXT TO 1; '
commands += 'SET CLIENT KEY ZEROTEXT TO 1;'
}
if (config.noblob) {
commands += 'SET CLIENT KEY NOBLOB TO 1; '
commands += 'SET CLIENT KEY NOBLOB TO 1;'
}
if (config.maxdata) {
commands += `SET CLIENT KEY MAXDATA TO ${config.maxdata}; `
commands += `SET CLIENT KEY MAXDATA TO ${config.maxdata};`
}
if (config.maxrows) {
commands += `SET CLIENT KEY MAXROWS TO ${config.maxrows}; `
commands += `SET CLIENT KEY MAXROWS TO ${config.maxrows};`
}
if (config.maxrowset) {
commands += `SET CLIENT KEY MAXROWSET TO ${config.maxrowset}; `
commands += `SET CLIENT KEY MAXROWSET TO ${config.maxrowset};`
}

// we ALWAYS set non linearizable to 1 when we start so we can be quicker on login
// but then we need to put it back to its default value if "linearizable" unless set
if (!config.non_linearizable) {
commands += 'SET CLIENT KEY NONLINEARIZABLE TO 0; '
commands += 'SET CLIENT KEY NONLINEARIZABLE TO 0;'
}

if (config.database) {
if (config.create && !config.memory) {
commands += `CREATE DATABASE ${config.database} IF NOT EXISTS; `
commands += `CREATE DATABASE ${config.database} IF NOT EXISTS;`
}
commands += `USE DATABASE ${config.database}; `
commands += `USE DATABASE ${config.database};`
}

return commands
Expand Down Expand Up @@ -177,16 +177,19 @@ export function validateConfiguration(config: SQLiteCloudConfig): SQLiteCloudCon
config.non_linearizable = parseBoolean(config.non_linearizable)
config.insecure = parseBoolean(config.insecure)

const hasCredentials = (config.username && config.password) || config.apikey
const hasCredentials = (config.username && config.password) || config.apikey || config.token
if (!config.host || !hasCredentials) {
console.error('SQLiteCloudConnection.validateConfiguration - missing arguments', config)
throw new SQLiteCloudError('The user, password and host arguments or the ?apikey= must be specified.', { errorCode: 'ERR_MISSING_ARGS' })
throw new SQLiteCloudError('The user, password and host arguments, the ?apikey= or the ?token= must be specified.', { errorCode: 'ERR_MISSING_ARGS' })
}

if (!config.connectionstring) {
// build connection string from configuration, values are already validated
config.connectionstring = `sqlitecloud://${config.host}:${config.port}/${config.database || ''}`
if (config.apikey) {
config.connectionstring = `sqlitecloud://${config.host}:${config.port}/${config.database || ''}?apikey=${config.apikey}`
config.connectionstring += `?apikey=${config.apikey}`
} else if (config.token) {
config.connectionstring += `?token=${config.token}`
} else {
config.connectionstring = `sqlitecloud://${encodeURIComponent(config.username || '')}:${encodeURIComponent(config.password || '')}@${config.host}:${
config.port
Expand Down Expand Up @@ -215,7 +218,7 @@ export function parseconnectionstring(connectionstring: string): SQLiteCloudConf
// all lowecase options
const options: { [key: string]: string } = {}
url.searchParams.forEach((value, key) => {
options[key.toLowerCase().replace(/-/g, '_')] = value
options[key.toLowerCase().replace(/-/g, '_')] = value.trim()
})

const config: SQLiteCloudConfig = {
Expand Down Expand Up @@ -243,6 +246,10 @@ export function parseconnectionstring(connectionstring: string): SQLiteCloudConf

// either you use an apikey or username and password
if (config.apikey) {
if (config.token) {
console.error('SQLiteCloudConnection.parseconnectionstring - apikey and token cannot be both specified')
throw new SQLiteCloudError('apikey and token cannot be both specified')
}
if (config.username || config.password) {
console.warn('SQLiteCloudConnection.parseconnectionstring - apikey and username/password are both specified, using apikey')
}
Expand All @@ -257,7 +264,7 @@ export function parseconnectionstring(connectionstring: string): SQLiteCloudConf

return config
} catch (error) {
throw new SQLiteCloudError(`Invalid connection string: ${connectionstring}`)
throw new SQLiteCloudError(`Invalid connection string: ${connectionstring} - error: ${error}`)
}
}

Expand Down
2 changes: 1 addition & 1 deletion test/connection-tls.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ it(
expect(error).toBeDefined()
expect(error).toBeInstanceOf(SQLiteCloudError)
const sqliteCloudError = error as SQLiteCloudError
expect(sqliteCloudError.message).toBe('The user, password and host arguments or the ?apikey= must be specified.')
expect(sqliteCloudError.message).toBe('The user, password and host arguments, the ?apikey= or the ?token= must be specified.')
expect(sqliteCloudError.errorCode).toBe('ERR_MISSING_ARGS')
expect(sqliteCloudError.externalErrorCode).toBeUndefined()
expect(sqliteCloudError.offsetCode).toBeUndefined()
Expand Down
16 changes: 15 additions & 1 deletion test/utilities.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//

import { SQLiteCloudError } from '../src/index'
import { parseconnectionstring, sanitizeSQLiteIdentifier } from '../src/drivers/utilities'
import { getInitializationCommands, parseconnectionstring, sanitizeSQLiteIdentifier } from '../src/drivers/utilities'
import { getTestingDatabaseName } from './shared'

import { expect, describe, it } from '@jest/globals'
Expand Down Expand Up @@ -190,3 +190,17 @@ describe('sanitizeSQLiteIdentifier()', () => {
expect(sanitized).toBe('"chinook.sql; DROP TABLE \"\"albums\"\""')
})
})

describe('getInitializationCommands()', () => {
it('should return commands with auth token command', () => {
const config = {
token: 'mytoken',
database: 'mydb',
}

const result = getInitializationCommands(config)

expect(result).toContain('AUTH TOKEN mytoken;')
expect(result).not.toContain('AUTH APIKEY')
})
})
Loading