feat: desktop app
Co-authored-by: Vivek R <123vivekr@gmail.com> Co-authored-by: Liyas Thomas <liyascthomas@gmail.com>
This commit is contained in:
@@ -72,6 +72,61 @@ describe("InterceptorService", () => {
|
||||
expect(service.currentInterceptorID.value).not.toEqual("unknown")
|
||||
})
|
||||
|
||||
it("currentInterceptor points to the instance of the currently selected interceptor", () => {
|
||||
const container = new TestContainer()
|
||||
|
||||
const service = container.bind(InterceptorService)
|
||||
|
||||
const interceptor = {
|
||||
interceptorID: "test",
|
||||
name: () => "test interceptor",
|
||||
selectable: { type: "selectable" as const },
|
||||
runRequest: () => {
|
||||
throw new Error("not implemented")
|
||||
},
|
||||
}
|
||||
|
||||
service.registerInterceptor(interceptor)
|
||||
service.currentInterceptorID.value = "test"
|
||||
|
||||
expect(service.currentInterceptor.value).toBe(interceptor)
|
||||
})
|
||||
|
||||
it("currentInterceptor updates when the currentInterceptorID changes", () => {
|
||||
const container = new TestContainer()
|
||||
|
||||
const service = container.bind(InterceptorService)
|
||||
|
||||
const interceptor = {
|
||||
interceptorID: "test",
|
||||
name: () => "test interceptor",
|
||||
selectable: { type: "selectable" as const },
|
||||
runRequest: () => {
|
||||
throw new Error("not implemented")
|
||||
},
|
||||
}
|
||||
|
||||
const interceptor_2 = {
|
||||
interceptorID: "test2",
|
||||
name: () => "test interceptor",
|
||||
selectable: { type: "selectable" as const },
|
||||
runRequest: () => {
|
||||
throw new Error("not implemented")
|
||||
},
|
||||
}
|
||||
|
||||
service.registerInterceptor(interceptor)
|
||||
service.registerInterceptor(interceptor_2)
|
||||
|
||||
service.currentInterceptorID.value = "test"
|
||||
|
||||
expect(service.currentInterceptor.value).toBe(interceptor)
|
||||
|
||||
service.currentInterceptorID.value = "test2"
|
||||
expect(service.currentInterceptor.value).not.toBe(interceptor)
|
||||
expect(service.currentInterceptor.value).toBe(interceptor_2)
|
||||
})
|
||||
|
||||
describe("registerInterceptor", () => {
|
||||
it("should register the interceptor", () => {
|
||||
const container = new TestContainer()
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
import { Service } from "dioc"
|
||||
import { ref } from "vue"
|
||||
import { parseString as setCookieParse } from "set-cookie-parser-es"
|
||||
|
||||
export type CookieDef = {
|
||||
name: string
|
||||
value: string
|
||||
domain: string
|
||||
path: string
|
||||
expires: string
|
||||
}
|
||||
|
||||
export class CookieJarService extends Service {
|
||||
public static readonly ID = "COOKIE_JAR_SERVICE"
|
||||
|
||||
/**
|
||||
* The cookie jar that stores all relevant cookie info.
|
||||
* The keys correspond to the domain of the cookie.
|
||||
* The cookie strings are stored as an array of strings corresponding to the domain
|
||||
*/
|
||||
public cookieJar = ref(new Map<string, string[]>())
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
}
|
||||
|
||||
public parseSetCookieString(setCookieString: string) {
|
||||
return setCookieParse(setCookieString)
|
||||
}
|
||||
|
||||
public bulkApplyCookiesToDomain(cookies: string[], domain: string) {
|
||||
const existingDomainEntries = this.cookieJar.value.get(domain) ?? []
|
||||
existingDomainEntries.push(...cookies)
|
||||
|
||||
this.cookieJar.value.set(domain, existingDomainEntries)
|
||||
}
|
||||
|
||||
public getCookiesForURL(url: URL) {
|
||||
const relevantDomains = Array.from(this.cookieJar.value.keys()).filter(
|
||||
(domain) => url.hostname.endsWith(domain)
|
||||
)
|
||||
|
||||
return relevantDomains
|
||||
.flatMap((domain) => {
|
||||
// Assemble the list of cookie entries from all the relevant domains
|
||||
|
||||
const cookieStrings = this.cookieJar.value.get(domain)! // We know not nullable from how we filter above
|
||||
|
||||
return cookieStrings.map((cookieString) =>
|
||||
this.parseSetCookieString(cookieString)
|
||||
)
|
||||
})
|
||||
.filter((cookie) => {
|
||||
// Perform the required checks on the cookies
|
||||
|
||||
const passesPathCheck = url.pathname.startsWith(cookie.path ?? "/")
|
||||
|
||||
const passesExpiresCheck = !cookie.expires
|
||||
? true
|
||||
: cookie.expires.getTime() >= new Date().getTime()
|
||||
|
||||
const passesSecureCheck = !cookie.secure
|
||||
? true
|
||||
: url.protocol === "https:"
|
||||
|
||||
return passesPathCheck && passesExpiresCheck && passesSecureCheck
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -85,6 +85,12 @@ export type Interceptor<Err extends InterceptorError = InterceptorError> = {
|
||||
*/
|
||||
name: (t: ReturnType<typeof getI18n>) => MaybeRef<string>
|
||||
|
||||
/**
|
||||
* Defines whether the interceptor has support for cookies.
|
||||
* If this field is undefined, it is assumed as not supporting cookies.
|
||||
*/
|
||||
supportsCookies?: boolean
|
||||
|
||||
/**
|
||||
* Defines what to render in the Interceptor section of the Settings page.
|
||||
* Use this space to define interceptor specific settings.
|
||||
@@ -161,6 +167,16 @@ export class InterceptorService extends Service {
|
||||
Array.from(this.interceptors.values())
|
||||
)
|
||||
|
||||
/**
|
||||
* Gives an instance to the current interceptor.
|
||||
* NOTE: Do not update from here, this is only for reading.
|
||||
*/
|
||||
public currentInterceptor = computed(() => {
|
||||
if (this.currentInterceptorID.value === null) return null
|
||||
|
||||
return this.interceptors.get(this.currentInterceptorID.value)
|
||||
})
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user