Skip to content

Commit

Permalink
fix fink login
Browse files Browse the repository at this point in the history
  • Loading branch information
janfjohannes committed May 23, 2024
1 parent e0889ad commit 39248e9
Show file tree
Hide file tree
Showing 11 changed files with 60 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ export const Gitfloat = () => {
ref={signInDialog}
onClickOnSignInButton={() => {
// hide the sign in dialog to increase UX when switching back to this window
browserAuth.login()
browserAuth.login({ redirect: window.location.origin + "/auth/auth-callback" })
signInDialog?.hide()
setSignInModalOpen(false)
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default function Page() {

createEffect(() => {
if (localStorage.user?.isLoggedIn && localStorage.user?.username) {
window.close()
setTimeout(() => window.close(), 100)
}
})

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// https://vike.dev/route-string
//
// this route is also hardcoded in the settings of the oauth app on github!
export default "/services/auth/auth-callback"
export default "/auth/auth-callback"
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export function LocalStorageProvider(props: { children: JSXElement }) {
// remove listener
if (typeof window !== "undefined") {
window.removeEventListener("message", onPostMessage)
window.removeEventListener("storage", onStorageSetByOtherWindow)
}
})

Expand All @@ -145,6 +146,8 @@ export function LocalStorageProvider(props: { children: JSXElement }) {
}
}

window.addEventListener("storage", onStorageSetByOtherWindow)

return (
<LocalStorageContext.Provider value={[store, setStore]}>
{props.children}
Expand Down
4 changes: 3 additions & 1 deletion inlang/source-code/manage/src/components/InlangInstall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,9 @@ export class InlangInstall extends TwLitElement {
class=${"bg-slate-800 text-white text-center py-2 rounded-md font-medium hover:bg-slate-900 transition-colors " +
(!this.module ? "cursor-not-allowed" : "")}
@click=${async () => {
await browserAuth.login()
await browserAuth.login({
redirect: window.location.origin + "/auth/auth-callback",
})
window.location.reload()
}}
>
Expand Down
8 changes: 6 additions & 2 deletions inlang/source-code/manage/src/components/InlangManage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,9 @@ export class InlangManage extends TwLitElement {
: typeof this.user === "undefined"
? html`<button
@click=${async () => {
await browserAuth.login()
await browserAuth.login({
redirect: window.location.origin + "/auth/auth-callback",
})
window.location.reload()
}}
target="_blank"
Expand Down Expand Up @@ -782,7 +784,9 @@ export class InlangManage extends TwLitElement {
</p>
<button
@click=${async () => {
await browserAuth.login()
await browserAuth.login({
redirect: window.location.origin + "/auth/auth-callback",
})
window.location.reload()
}}
target="_blank"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// https://vike.dev/route-string
//
// this route is also hardcoded in the settings of the oauth app on github!
export default "/services/auth/auth-callback"
export default "/auth/auth-callback"
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@ export function LocalStorageProvider(props: { children: JSXElement }) {

/** custom setStore to trigger localStorage.setItem on change */
const setStore: typeof setOriginStore = (...args: any) => {
// @ts-ignore
setOriginStore(...args)
// write to local storage
localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(store))

Expand All @@ -71,6 +69,8 @@ export function LocalStorageProvider(props: { children: JSXElement }) {
referrer
)
}
// @ts-ignore
setOriginStore(...args)
}

// read from local storage on mount
Expand Down Expand Up @@ -121,6 +121,7 @@ export function LocalStorageProvider(props: { children: JSXElement }) {
// remove listener
if (typeof window !== "undefined") {
window.removeEventListener("message", onPostMessage)
window.removeEventListener("storage", onStorageSetByOtherWindow)
}
})

Expand All @@ -146,6 +147,8 @@ export function LocalStorageProvider(props: { children: JSXElement }) {
}
}

window.addEventListener("storage", onStorageSetByOtherWindow)

return (
<LocalStorageContext.Provider value={[store, setStore]}>
{props.children}
Expand Down
6 changes: 4 additions & 2 deletions lix/packages/client/src/browser-auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ export function getAuthClient({
* Read https://docs.github.com/en/developers/apps/building-oauth-apps/authorizing-oauth-apps#1-request-a-users-github-identity
* works only in browsers for now, but other methods should be supported in future
*/
async login() {
async login({ redirect } = { redirect: "" }) {
const loginWindow = window.open(
`https://github.com/login/oauth/authorize?client_id=${githubAppClientId}`, // &redirect_uri=${
`https://github.com/login/oauth/authorize?client_id=${githubAppClientId}${
redirect ? "&state=" + encodeURI(redirect) : ""
}`,
"_blank"
)

Expand Down
2 changes: 2 additions & 0 deletions lix/packages/fs/src/memoryFs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ export function createNodeishMemoryFs(): NodeishFilesystem {

const listeners: Set<(event: FileChangeInfo) => void> = new Set()

// MISSING: exists and reddir with recursive option

async function stat(path: Parameters<NodeishFilesystem["stat"]>[0]): Promise<NodeishStats> {
path = normalPath(path)
const stats: NodeishStats | undefined = state.fsStats.get(path)
Expand Down
54 changes: 33 additions & 21 deletions lix/packages/server/src/auth/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,28 @@ export const router: Router = Router()
const PUBLIC_LIX_GITHUB_APP_NAME = getEnvVar("PUBLIC_LIX_GITHUB_APP_NAME")
const installUrl = `https://github.com/apps/${PUBLIC_LIX_GITHUB_APP_NAME}/installations/new`

const PUBLIC_SERVER_BASE_URL = getEnvVar("PUBLIC_SERVER_BASE_URL", {
descirption: "The base url of the server e.g. https://inlang.com - Must not end with a slash",
})
const callbackUrl = `${PUBLIC_SERVER_BASE_URL}/services/auth/auth-callback`

const PUBLIC_LIX_GITHUB_APP_CLIENT_ID = getEnvVar("PUBLIC_LIX_GITHUB_APP_CLIENT_ID")
const LIX_GITHUB_APP_CLIENT_SECRET = getEnvVar("LIX_GITHUB_APP_CLIENT_SECRET")
const PUBLIC_ALLOWED_AUTH_URLS = getEnvVar("PUBLIC_ALLOWED_AUTH_URLS")
const JWE_SECRET = getEnvVar("JWE_SECRET")

const allowedAuthUrls = PUBLIC_ALLOWED_AUTH_URLS.split(",")

/**
* OAuth flow from GitHub
*
* Be aware that the route set here is prefixed with /services/auth
* and that the route is set in the GitHub app settings.
*/

const allowedAuthUrls = PUBLIC_ALLOWED_AUTH_URLS.split(",")
router.get("/github-auth-callback", async (request, response, next) => {
const callbackUrl = decodeURI((request.query["state"] as string) || "") as string

const callBackOrigin = new URL(callbackUrl).origin
if (!allowedAuthUrls.includes(callBackOrigin)) {
return next(new Error("Origin not allowed"))
}

try {
// TODO: org installation
// TODO: test harness
Expand All @@ -44,33 +47,42 @@ router.get("/github-auth-callback", async (request, response, next) => {
githubAppClientId: PUBLIC_LIX_GITHUB_APP_CLIENT_ID,
githubClientSecret: LIX_GITHUB_APP_CLIENT_SECRET,
})

const { installations } = await (
await fetch(`https://api.github.com/user/installations`, {
headers: {
Accept: "application/vnd.github+json",
"X-GitHub-Api-Version": "2022-11-28",
authorization: `Bearer ${access_token}`,
},
})
).json()

const encryptedAccessToken = await encryptAccessToken({
accessToken: access_token,
JWE_SECRET_KEY: JWE_SECRET,
})

// set the session
request.session = {
encryptedAccessToken,
}

// we currently do not support org installations, we only look at user installations for now in case someone accidentally installs the app as org
const [{ installations }, user] = await Promise.all([
fetch(`https://api.github.com/user/installations`, {
headers: {
Accept: "application/vnd.github+json",
"X-GitHub-Api-Version": "2022-11-28",
authorization: `Bearer ${access_token}`,
},
}).then((response) => response.json()),
fetch(`https://api.github.com/user`, {
headers: {
Accept: "application/vnd.github+json",
"X-GitHub-Api-Version": "2022-11-28",
authorization: `Bearer ${access_token}`,
},
}).then((response) => response.json()),
])

// we currently do not support org installations, we only look at user installations for now in case someone accidentally installs the app as org,
// we also see installations of everyone in our organization who isntalled the same app as user, so we need to filter out only our own!
if (
installations.filter((installation: any) => installation.target_type === "User").length === 0
installations.filter(
(installation: any) =>
installation.target_type === "User" && user.id === installation.account?.id
).length === 0
) {
// if app not installed, redirect via the install permissions url
response.redirect(installUrl)
response.redirect(installUrl + "?state=" + encodeURIComponent(callbackUrl))
} else {
response.redirect(callbackUrl)
}
Expand Down

0 comments on commit 39248e9

Please sign in to comment.