mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-12 10:36:44 +00:00
fix deps, tsconfig, next-env-vars, zitadel api
This commit is contained in:
33
apps/login/next-env-vars.d.ts
vendored
Normal file
33
apps/login/next-env-vars.d.ts
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
declare namespace NodeJS {
|
||||
interface ProcessEnv {
|
||||
/**
|
||||
* The system api url
|
||||
*/
|
||||
AUDIENCE: string;
|
||||
|
||||
/**
|
||||
* The system api service user ID
|
||||
*/
|
||||
SYSTEM_USER_ID: string;
|
||||
|
||||
/**
|
||||
* The service user key
|
||||
*/
|
||||
SYSTEM_USER_PRIVATE_KEY: string;
|
||||
|
||||
/**
|
||||
* The instance url
|
||||
*/
|
||||
ZITADEL_API_URL: string;
|
||||
|
||||
/**
|
||||
* The service user id for the instance
|
||||
*/
|
||||
ZITADEL_USER_ID: string;
|
||||
|
||||
/**
|
||||
* The service user token for the instance
|
||||
*/
|
||||
ZITADEL_USER_TOKEN: string;
|
||||
}
|
||||
}
|
||||
@@ -44,14 +44,15 @@
|
||||
"clsx": "1.2.1",
|
||||
"copy-to-clipboard": "^3.3.3",
|
||||
"deepmerge": "^4.3.1",
|
||||
"jose": "^5.3.0",
|
||||
"moment": "^2.29.4",
|
||||
"next": "15.0.4-canary.23",
|
||||
"next-intl": "^3.25.1",
|
||||
"next-themes": "^0.2.1",
|
||||
"nice-grpc": "2.0.1",
|
||||
"qrcode.react": "^3.1.0",
|
||||
"react": "19.0.0-rc-66855b96-20241106",
|
||||
"react-dom": "19.0.0-rc-66855b96-20241106",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"react-hook-form": "7.39.5",
|
||||
"swr": "^2.2.0",
|
||||
"tinycolor2": "1.4.2"
|
||||
@@ -62,19 +63,20 @@
|
||||
"@testing-library/react": "^16.0.1",
|
||||
"@types/ms": "0.7.34",
|
||||
"@types/node": "22.9.0",
|
||||
"@types/react": "npm:types-react@19.0.0-rc.1",
|
||||
"@types/react-dom": "npm:types-react-dom@19.0.0-rc.1",
|
||||
"@types/react": "19.0.2",
|
||||
"@types/react-dom": "19.0.2",
|
||||
"@types/tinycolor2": "1.4.3",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@vercel/git-hooks": "1.0.0",
|
||||
"@zitadel/eslint-config": "workspace:*",
|
||||
"@zitadel/prettier-config": "workspace:*",
|
||||
"@zitadel/tailwind-config": "workspace:*",
|
||||
"@zitadel/tsconfig": "workspace:*",
|
||||
"autoprefixer": "10.4.20",
|
||||
"concurrently": "^9.1.0",
|
||||
"cypress": "^13.15.2",
|
||||
"del-cli": "6.0.0",
|
||||
"env-cmd": "^10.0.0",
|
||||
"@zitadel/eslint-config": "workspace:*",
|
||||
"grpc-tools": "1.12.4",
|
||||
"jsdom": "^25.0.1",
|
||||
"lint-staged": "15.2.10",
|
||||
@@ -86,7 +88,6 @@
|
||||
"start-server-and-test": "^2.0.8",
|
||||
"tailwindcss": "3.4.14",
|
||||
"ts-proto": "^2.2.7",
|
||||
"typescript": "^5.6.3",
|
||||
"@zitadel/tailwind-config": "workspace:*"
|
||||
"typescript": "^5.6.3"
|
||||
}
|
||||
}
|
||||
|
||||
36
apps/login/src/lib/api.ts
Normal file
36
apps/login/src/lib/api.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { importPKCS8, SignJWT } from "jose";
|
||||
import { getInstanceByHost } from "./zitadel";
|
||||
|
||||
export async function getInstanceUrl(host: string): Promise<string> {
|
||||
const instance = await getInstanceByHost(host);
|
||||
const generatedDomain = instance.domains.find(
|
||||
(domain) => domain.generated === true,
|
||||
);
|
||||
|
||||
if (!generatedDomain?.domain) {
|
||||
throw new Error("No generated domain found");
|
||||
}
|
||||
|
||||
console.log(`host: ${host}, api: ${generatedDomain?.domain}`);
|
||||
|
||||
return generatedDomain?.domain;
|
||||
}
|
||||
|
||||
export async function systemAPIToken() {
|
||||
const audience = process.env.AUDIENCE;
|
||||
const userID = process.env.SYSTEM_USER_ID;
|
||||
const key = process.env.SYSTEM_USER_PRIVATE_KEY;
|
||||
|
||||
const decodedToken = Buffer.from(key, "base64").toString("utf-8");
|
||||
|
||||
const token = new SignJWT({})
|
||||
.setProtectedHeader({ alg: "RS256" })
|
||||
.setIssuedAt()
|
||||
.setExpirationTime("1h")
|
||||
.setIssuer(userID)
|
||||
.setSubject(userID)
|
||||
.setAudience(audience)
|
||||
.sign(await importPKCS8(decodedToken, "RS256"));
|
||||
|
||||
return token;
|
||||
}
|
||||
@@ -1,32 +1,22 @@
|
||||
import { create, createClientFor, Duration } from "@zitadel/client";
|
||||
import { createServerTransport } from "@zitadel/client/node";
|
||||
import {
|
||||
createIdpServiceClient,
|
||||
createOIDCServiceClient,
|
||||
createOrganizationServiceClient,
|
||||
createSessionServiceClient,
|
||||
createSettingsServiceClient,
|
||||
createUserServiceClient,
|
||||
makeReqCtx,
|
||||
} from "@zitadel/client/v2";
|
||||
import { RequestChallenges } from "@zitadel/proto/zitadel/session/v2/challenge_pb";
|
||||
import { Checks } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
|
||||
import {
|
||||
AddHumanUserRequest,
|
||||
ResendEmailCodeRequest,
|
||||
ResendEmailCodeRequestSchema,
|
||||
RetrieveIdentityProviderIntentRequest,
|
||||
SendEmailCodeRequestSchema,
|
||||
SetPasswordRequest,
|
||||
SetPasswordRequestSchema,
|
||||
VerifyPasskeyRegistrationRequest,
|
||||
VerifyU2FRegistrationRequest,
|
||||
} from "@zitadel/proto/zitadel/user/v2/user_service_pb";
|
||||
|
||||
import { create, Duration } from "@zitadel/client";
|
||||
import { createSystemServiceClient } from "@zitadel/client/v1";
|
||||
import { makeReqCtx } from "@zitadel/client/v2";
|
||||
import { IdentityProviderService } from "@zitadel/proto/zitadel/idp/v2/idp_service_pb";
|
||||
import { TextQueryMethod } from "@zitadel/proto/zitadel/object/v2/object_pb";
|
||||
import { CreateCallbackRequest } from "@zitadel/proto/zitadel/oidc/v2/oidc_service_pb";
|
||||
import {
|
||||
CreateCallbackRequest,
|
||||
OIDCService,
|
||||
} from "@zitadel/proto/zitadel/oidc/v2/oidc_service_pb";
|
||||
import { Organization } from "@zitadel/proto/zitadel/org/v2/org_pb";
|
||||
import { OrganizationService } from "@zitadel/proto/zitadel/org/v2/org_service_pb";
|
||||
import { RequestChallenges } from "@zitadel/proto/zitadel/session/v2/challenge_pb";
|
||||
import {
|
||||
Checks,
|
||||
SessionService,
|
||||
} from "@zitadel/proto/zitadel/session/v2/session_service_pb";
|
||||
import { LoginSettings } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
|
||||
import { SettingsService } from "@zitadel/proto/zitadel/settings/v2/settings_service_pb";
|
||||
import { SendEmailVerificationCodeSchema } from "@zitadel/proto/zitadel/user/v2/email_pb";
|
||||
import type { RedirectURLsJson } from "@zitadel/proto/zitadel/user/v2/idp_pb";
|
||||
import {
|
||||
@@ -42,19 +32,20 @@ import {
|
||||
User,
|
||||
UserState,
|
||||
} from "@zitadel/proto/zitadel/user/v2/user_pb";
|
||||
import {
|
||||
AddHumanUserRequest,
|
||||
ResendEmailCodeRequest,
|
||||
ResendEmailCodeRequestSchema,
|
||||
RetrieveIdentityProviderIntentRequest,
|
||||
SendEmailCodeRequestSchema,
|
||||
SetPasswordRequest,
|
||||
SetPasswordRequestSchema,
|
||||
UserService,
|
||||
VerifyPasskeyRegistrationRequest,
|
||||
VerifyU2FRegistrationRequest,
|
||||
} from "@zitadel/proto/zitadel/user/v2/user_service_pb";
|
||||
import { unstable_cacheLife as cacheLife } from "next/cache";
|
||||
|
||||
const transport = createServerTransport(
|
||||
process.env.ZITADEL_SERVICE_USER_TOKEN!,
|
||||
{ baseUrl: process.env.ZITADEL_API_URL! },
|
||||
);
|
||||
|
||||
export const sessionService = createSessionServiceClient(transport);
|
||||
export const userService = createUserServiceClient(transport);
|
||||
export const oidcService = createOIDCServiceClient(transport);
|
||||
export const idpService = createIdpServiceClient(transport);
|
||||
export const orgService = createOrganizationServiceClient(transport);
|
||||
export const settingsService = createSettingsServiceClient(transport);
|
||||
import { systemAPIToken } from "./api";
|
||||
|
||||
const useCache = process.env.DEBUG !== "true";
|
||||
|
||||
@@ -65,6 +56,86 @@ async function cacheWrapper<T>(callback: Promise<T>) {
|
||||
return callback;
|
||||
}
|
||||
|
||||
type ServiceClass =
|
||||
| typeof IdentityProviderService
|
||||
| typeof UserService
|
||||
| typeof OrganizationService
|
||||
| typeof SessionService
|
||||
| typeof OIDCService
|
||||
| typeof SettingsService;
|
||||
|
||||
async function createServiceForHost<T extends ServiceClass>(service: T) {
|
||||
// const host = headers().get("X-Forwarded-Host");
|
||||
// if (!host) {
|
||||
// throw new Error("No host header found!");
|
||||
// }
|
||||
|
||||
// let instanceUrl;
|
||||
// try {
|
||||
// instanceUrl = await getInstanceUrl(host);
|
||||
// } catch (error) {
|
||||
// console.error(
|
||||
// "Could not get instance url, fallback to ZITADEL_API_URL",
|
||||
// error,
|
||||
// );
|
||||
// instanceUrl = process.env.ZITADEL_API_URL;
|
||||
// }
|
||||
|
||||
// remove in favor of the above
|
||||
const instanceUrl = process.env.ZITADEL_API_URL;
|
||||
|
||||
const systemToken = await systemAPIToken();
|
||||
|
||||
const transport = createServerTransport(systemToken, {
|
||||
baseUrl: instanceUrl,
|
||||
});
|
||||
|
||||
return createClientFor<T>(service)(transport);
|
||||
}
|
||||
|
||||
const idpService = await createServiceForHost(IdentityProviderService);
|
||||
const orgService = await createServiceForHost(OrganizationService);
|
||||
export const sessionService = await createServiceForHost(SessionService);
|
||||
const userService = await createServiceForHost(UserService);
|
||||
const oidcService = await createServiceForHost(OIDCService);
|
||||
const settingsService = await createServiceForHost(SettingsService);
|
||||
|
||||
const systemService = async () => {
|
||||
const systemToken = await systemAPIToken();
|
||||
|
||||
const transport = createServerTransport(systemToken, {
|
||||
baseUrl: process.env.ZITADEL_API_URL,
|
||||
});
|
||||
|
||||
return createSystemServiceClient(transport);
|
||||
};
|
||||
|
||||
export async function getInstanceByHost(host: string) {
|
||||
return (await systemService())
|
||||
.listInstances(
|
||||
{
|
||||
queries: [
|
||||
{
|
||||
query: {
|
||||
case: "domainQuery",
|
||||
value: {
|
||||
domains: [host],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{},
|
||||
)
|
||||
.then((resp) => {
|
||||
if (resp.result.length !== 1) {
|
||||
throw new Error("Could not find instance");
|
||||
}
|
||||
|
||||
return resp.result[0];
|
||||
});
|
||||
}
|
||||
|
||||
export async function getBrandingSettings(organization?: string) {
|
||||
const callback = settingsService
|
||||
.getBrandingSettings({ ctx: makeReqCtx(organization) }, {})
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"extends": "@zitadel/tsconfig/nextjs.json",
|
||||
"compilerOptions": {
|
||||
"jsx": "preserve",
|
||||
"target": "es2022",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
|
||||
Reference in New Issue
Block a user