Skip to content

Commit

Permalink
refactor(ts): auth
Browse files Browse the repository at this point in the history
  • Loading branch information
arildm committed Jul 18, 2024
1 parent 9091553 commit f9b13b9
Show file tree
Hide file tree
Showing 12 changed files with 255 additions and 248 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- CQP queries
- CorpusListing
- `$rootScope`
- Auth module

### Changed

Expand Down
2 changes: 1 addition & 1 deletion app/scripts/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ korpApp.filter(
input === "" ? "–" : input
)

authenticationProxy.initAngular()
authenticationProxy.initAngular(korpApp)

/**
* angular-dynamic-locale updates translations in the builtin $locale service, which is used
Expand Down
50 changes: 0 additions & 50 deletions app/scripts/components/auth/auth.js

This file was deleted.

39 changes: 39 additions & 0 deletions app/scripts/components/auth/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/** @format */
import statemachine from "@/statemachine"
import settings from "@/settings"
import { AuthModule } from "./auth.types"

function findAuthModule(): AuthModule | undefined {
const authModuleName = settings["auth_module"]?.["module"] || settings["auth_module"]
if (authModuleName == "federated_auth") {
return require("./federatedauth/fed_auth")
}
if (authModuleName == "basic_auth" || authModuleName == undefined) {
// load the default athentication
return require("./basic_auth")
}

// must be a custom auth module
try {
return require("custom/" + authModuleName)
} catch (error) {
console.log("Auth module not available: ", authModule)
}
}

const authModule = findAuthModule()

export async function init(): Promise<boolean> {
const loggedIn = await authModule.init()
statemachine.send(loggedIn ? "USER_FOUND" : "USER_NOT_FOUND")
return loggedIn
}

export const initAngular = authModule.initAngular
export const login = authModule.login
export const logout = authModule.logout
export const getCredentials = authModule.getCredentials
export const isLoggedIn = authModule.isLoggedIn
export const getUsername = authModule.getUsername
export const getAuthorizationHeader = authModule.getAuthorizationHeader
export const hasCredential = authModule.hasCredential
25 changes: 25 additions & 0 deletions app/scripts/components/auth/auth.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/** @format */

import { IModule } from "angular"

export type AuthModule = {
/**
* Check if logged in.
* This is called before Angular app is initialized.
*/
init: () => boolean | Promise<boolean>
/** Initialize in Angular context (add login form components etc) */
initAngular: (korpApp: IModule) => void
/** Trigger interactive authentication workflow */
login: Function
/** Trigger logout */
logout: () => void
/** Get headers to include in API requests */
getAuthorizationHeader: () => Record<string, string>
/** Check if user has access to a given corpus */
hasCredential: (corpusId: string) => boolean
/** Get corpus ids the user has access to */
getCredentials: () => string[]
getUsername: () => string
isLoggedIn: () => boolean
}
Original file line number Diff line number Diff line change
@@ -1,59 +1,57 @@
/** @format */
import _ from "lodash"
import { IModule } from "angular"
import settings from "@/settings"
import { localStorageGet, localStorageSet } from "@/local-storage"
import { loginBoxComponent } from "./login_box"
import { loginStatusComponent } from "./login_status"
import { localStorageGet, localStorageSet } from "@/local-storage"
import { AuthState, LoginResponseData } from "./basic_auth.types"

const state = {}
const state: AuthState = {}

const init = () => {
export const init = () => {
const creds = localStorageGet("creds")
if (creds) {
state.loginObj = creds
}
return !_.isEmpty(creds)
}

const initAngular = () => {
const korpApp = angular.module("korpApp")

export const initAngular = (korpApp: IModule) => {
korpApp.component("loginStatus", loginStatusComponent)
korpApp.component("loginBox", loginBoxComponent)
}

const getAuthorizationHeader = () => {
if (!_.isEmpty(state.loginObj)) {
return { Authorization: `Basic ${state.loginObj.auth}` }
} else {
return {}
}
}
export const getAuthorizationHeader = () =>
!_.isEmpty(state.loginObj) ? { Authorization: `Basic ${state.loginObj.auth}` } : {}

function toBase64(str) {
function toBase64(str: string) {
// copied from https://stackoverflow.com/a/43271130
function u_btoa(buffer) {
var binary = []
var bytes = new Uint8Array(buffer)
for (var i = 0, il = bytes.byteLength; i < il; i++) {
function u_btoa(buffer: Uint8Array | Buffer) {
const binary = []
const bytes = new Uint8Array(buffer)
for (let i = 0; i < bytes.byteLength; i++) {
binary.push(String.fromCharCode(bytes[i]))
}
return window.btoa(binary.join(""))
}
return u_btoa(new TextEncoder().encode(str))
}

const login = (usr, pass, saveLogin) => {
export const login = (usr: string, pass: string, saveLogin: boolean): JQueryDeferred<LoginResponseData> => {
const auth = toBase64(usr + ":" + pass)

const dfd = $.Deferred()
$.ajax({

const ajaxSettings: JQuery.AjaxSettings = {
url: settings["korp_backend_url"] + "/authenticate",
type: "GET",
beforeSend(req) {
return req.setRequestHeader("Authorization", `Basic ${auth}`)
},
})
}

;($.ajax(ajaxSettings) as JQuery.jqXHR<LoginResponseData>)
.done(function (data, status, xhr) {
if (!data.corpora) {
dfd.reject()
Expand All @@ -77,32 +75,15 @@ const login = (usr, pass, saveLogin) => {
return dfd
}

const hasCredential = (corpusId) => {
if (!state.loginObj?.credentials) {
return false
}
return state.loginObj.credentials.includes(corpusId.toUpperCase())
}
export const hasCredential = (corpusId: string): boolean => state.loginObj.credentials?.includes(corpusId.toUpperCase())

const logout = () => {
state.loginObj = {}
export const logout = (): void => {
state.loginObj = undefined
localStorage.removeItem("creds")
}

const getCredentials = () => state.loginObj?.credentials || []

const getUsername = () => state.loginObj.name
export const getCredentials = (): string[] => state.loginObj?.credentials || []

const isLoggedIn = () => !_.isEmpty(state.loginObj)
export const getUsername = () => state.loginObj.name

export {
init,
initAngular,
login,
logout,
getAuthorizationHeader,
hasCredential,
getCredentials,
getUsername,
isLoggedIn,
}
export const isLoggedIn = () => !_.isEmpty(state.loginObj)
15 changes: 15 additions & 0 deletions app/scripts/components/auth/basic_auth.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/** @format */
import { Creds } from "@/local-storage"

export type AuthState = {
loginObj?: Creds
}

export type LoginResponseData = {
corpora: string[]
}

export type AuthModuleOptions = {
show_remember?: boolean
default_value_remember?: boolean
}
116 changes: 0 additions & 116 deletions app/scripts/components/auth/federatedauth/fed_auth.js

This file was deleted.

Loading

0 comments on commit f9b13b9

Please sign in to comment.