Skip to content
Open
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
50 changes: 32 additions & 18 deletions templates/ords-remix-jwt-sample/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,41 @@
# All rights reserved
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/

# We refer to some variables as Autonomous Database specific
# but you can use whichever ORDS URL you want/have as well as the user,
# as long as this user is capable of creating and REST Enabling other schemas.
ADB_ORDS_URL=https://example.com:8080/ords/
ADB_ADMIN_USER=username
ADB_ADMIN_PASSWORD=
# ORDS base URL for your Base Database or ORDS instance.
# Replace <VM-PUBLIC-IP>, <VM-PORT>, and <POOL_NAME> with your actual values.
# Keep the trailing slash.
BD_ORDS_URL=http://<VM-PUBLIC-IP>:<VM-PORT>/ords/<POOL_NAME>

# Oracle Database connect string used by migrate/seed/drop scripts.
# Examples:
# host:1521/service_name
# myadb_high (from tnsnames.ora when TNS_ADMIN is configured)
BD_CONNECT_STRING=<HOST>:<PORT>/<SERVICE_NAME>

# Oracle Instant Client directory for Thick mode in node-oracledb.
ORACLE_CLIENT_LIB_DIR=<path>/instantclient_23_26

# OCI IAM JWT credentials, used by ORDS to validate request to protected endpoints.
JWT_ISSUER=https://identity.oraclecloud.com/
JWT_VERIFICATION_KEY=https://<domain-url>:443/admin/v1/SigningCert/jwk
JWT_AUDIENCE=ords/sample-app/

BD_ADMIN_USER=BD_admin
BD_ADMIN_PASSWORD=

# The name of the schema that will be created to host all of the
# ORDS Concert App database objects.
SCHEMA_NAME=ORDS_CONCERT_APP
SCHEMA_PASSWORD=

# Your Auth0 tenant JWT credentials, used by ORDS to validate request to protected endpoints.
JWT_ISSUER=https://my-domain.auth0.com/
JWT_VERIFICATION_KEY=https://my-domain.auth0.com/oauth/token/.well-known/jwks.json
JWT_AUDIENCE=https://concert.sample.app

# Auth0 Authentication app configuration parameters specific of the sample app.
AUTH0_RETURN_TO_URL=http://localhost:3000
AUTH0_CALLBACK_URL=http://localhost:3000/callback
AUTH0_CLIENT_ID=auth0_client_id
AUTH0_CLIENT_SECRET=auth0_client_secret
AUTH0_DOMAIN=my-domain.auth0.com
AUTH0_LOGOUT_URL=https://my-domain.auth0.com/v2/logout
# OCI IAM OIDC application configuration parameters specific to the sample app.
OIDC_RETURN_TO_URL=http://localhost:3000
OIDC_REDIRECT_URI=http://localhost:3000/callback
OIDC_CLIENT_ID=<CLIENT_ID>
OIDC_CLIENT_SECRET=<CLIENT_SECRET>
OIDC_AUTHORIZATION_ENDPOINT=https://<domain-url>:443/oauth2/v1/authorize
OIDC_TOKEN_ENDPOINT=https://<domain-url>:443/oauth2/v1/token
OIDC_USERINFO_ENDPOINT=https://<domain-url>:443/oauth2/v1/userinfo
OIDC_LOGOUT_ENDPOINT=https://<domain-url>:443/oauth2/v1/userlogout
OIDC_AUDIENCE=ords/sample-app/
OIDC_SCOPES=openid,email,profile,ords/sample-app/concert_app_authuser,ords/sample-app/concert_app_admin
20 changes: 20 additions & 0 deletions templates/ords-remix-jwt-sample/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# MacOS
.DS_Store
.DS_Store?

# Visual Studio Code
.vscode/

# Node and NPM installation folder
/node

# Node Modules
node_modules/

# Remix
/.cache
/build
/public/build

# Enviorement variables
.env
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import Artist from '../../models/Artist';
import EventStatus from '../../models/EventStatus';
import ORDSResponse from '../../models/ORDSResponse';
import Venue from '../../models/Venue';
import { BASE } from '../../routes/constants/index.server';
import TooltipComponent from '../tooltips/TooltipComponent';
import featureDescriptions from '../../utils/ORDSFeaturesDescription';

Expand All @@ -34,15 +33,15 @@ function EventForm(props: EventFormProps) {
const [eventStatus, setEventStatus] = React.useState(status.items[0].event_status_id);
const handleArtistSelect = (event: React.FormEvent<EventTarget>) => {
const target = event.target as HTMLInputElement;
setArtist(parseInt(target.value, BASE));
setArtist(parseInt(target.value, 10));
};
const handleVenueSelect = (event: React.FormEvent<EventTarget>) => {
const target = event.target as HTMLInputElement;
setVenue(parseInt(target.value, BASE));
setVenue(parseInt(target.value, 10));
};
const handleStatusSelect = (event: React.FormEvent<EventTarget>) => {
const target = event.target as HTMLInputElement;
setEventStatus(parseInt(target.value, BASE));
setEventStatus(parseInt(target.value, 10));
};
return (
<div className="flex flex-row">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { Form } from '@remix-run/react';
import React from 'react';
import City from '../../models/City';
import ORDSResponse from '../../models/ORDSResponse';
import { BASE } from '../../routes/constants/index.server';

interface VenuesFormProps {
cities: ORDSResponse<City>
Expand All @@ -25,7 +24,7 @@ function VenuesForm(props: VenuesFormProps) {

const handleCitySelect = (event: React.FormEvent<EventTarget>) => {
const target = event.target as HTMLInputElement;
setCity(parseInt(target.value, BASE));
setCity(parseInt(target.value, 10));
};

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*/
import React from 'react';
import { Divider } from '@mui/material';
import { Auth0Profile } from 'remix-auth-auth0';
import HeroBanner from './HeroBanner';
import Countdown from '../homepage/Countdown';
import Timeline from '../homepage/Timeline';
Expand All @@ -15,12 +14,13 @@ import DiscoverArtists from './DiscoverArtists';
import Artist from '../../models/Artist';
import ORDSResponse from '../../models/ORDSResponse';
import ORDSConcert from '../../models/ORDSConcert';
import OIDCProfile from '../../models/OIDCProfile';

interface ArtistHomeProps {
artists: ORDSResponse< Artist>;
events: ORDSResponse< ORDSConcert >;
similarArtists: ORDSResponse< Artist >;
user: Auth0Profile | null;
user: OIDCProfile | null;
likedArtist: boolean;
}
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import React from 'react';
import {
Box, CircularProgress, Modal, Chip,
} from '@mui/material';
import { Auth0Profile } from 'remix-auth-auth0';
import { Form, useNavigation, useSearchParams } from '@remix-run/react';
import Artist from '../../models/Artist';
import { modalStyle } from '../../CommonStyles';
Expand All @@ -20,10 +19,11 @@ import artistImages from '../utils/artistImages';
import artistBackgrounds from '../utils/artistBackgrounds';
import artistBioColor from '../utils/artistBioTextColor';
import artistTitleColor from '../utils/artistTitleColor';
import OIDCProfile from '../../models/OIDCProfile';

interface HeroBannerProps {
artist: Artist;
user: Auth0Profile | null;
user: OIDCProfile | null;
userLikedArtist: boolean;
}

Expand Down Expand Up @@ -160,7 +160,7 @@ function HeroBanner(props: HeroBannerProps) {
100 followers
</p>
</div>
<Form method="post" action="/auth0" className="flex w-2/5 justify-center">
<Form method="post" action="/oidc" className="flex w-2/5 justify-center">
<button type="submit" className="w-2/5 rounded-3xl bg-red-600 py-4 text-white">
Sign in
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ function ConcertBanner(props : ConcertBannerProps) {
people going
</p>
</div>
<Form method="post" action="/auth0">
<Form method="post" action="/oidc">
<button
className="rounded bg-red-600 px-4 py-2 text-xs text-white hover:bg-red-500"
type="submit"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function ErrorComponent(props: ErrorPageProps) {
{
error.status === HTTP_UNAUTHORIZED_CODE && (
<div className="p-4">
<Form method="post" action="/auth0">
<Form method="post" action="/oidc">
<button
className="rounded bg-red-600 px-8 py-2 text-white hover:bg-red-500"
type="submit"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ function NavBar(props: NavBarProps) {
user === null
? (
<li className="w-full">
<Form method="post" action="/auth0">
<Form method="post" action="/oidc">
<button
className="rounded bg-red-600 px-4 py-2 text-xs text-white hover:bg-red-500"
type="submit"
Expand Down
4 changes: 2 additions & 2 deletions templates/ords-remix-jwt-sample/app/models/ConcertProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
** All rights reserved
** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
*/
import { Auth0Profile } from 'remix-auth-auth0';
import Concert from './ORDSConcert';
import ORDSResponse from './ORDSResponse';
import OIDCProfile from './OIDCProfile';

interface ConcertBannerProps {
user : Auth0Profile | null;
user : OIDCProfile | null;
concert: ORDSResponse<Concert>;
likedConcert: boolean;
}
Expand Down
4 changes: 2 additions & 2 deletions templates/ords-remix-jwt-sample/app/models/NavBarProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
** All rights reserved
** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
*/
import { Auth0Profile } from 'remix-auth-auth0';
import City from './City';
import ORDSResponse from './ORDSResponse';
import OIDCProfile from './OIDCProfile';

interface NavBarProps {
user: Auth0Profile | null;
user: OIDCProfile | null;
cities: ORDSResponse< City >;
}

Expand Down
21 changes: 21 additions & 0 deletions templates/ords-remix-jwt-sample/app/models/OIDCProfile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
**
** Copyright (c) 2024, Oracle and/or its affiliates.
** All rights reserved
** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
*/
import type { OAuth2Profile } from 'remix-auth-oauth2';

interface OIDCProfile extends OAuth2Profile {
provider: string;
id: string;
displayName: string;
emails: Array<{ value: string; type?: string }>;
photos: Array<{ value: string }>;
_json?: {
nickname?: string;
[key: string]: unknown;
};
}

export default OIDCProfile;
2 changes: 1 addition & 1 deletion templates/ords-remix-jwt-sample/app/routes/auth0.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ import { auth } from '~/utils/auth.server';

export const loader = async () => redirect('/');

export const action = async ({ request }: ActionFunctionArgs) => auth.authenticate('auth0', request);
export const action = async ({ request }: ActionFunctionArgs) => auth.authenticate('oidc', request);
2 changes: 1 addition & 1 deletion templates/ords-remix-jwt-sample/app/routes/callback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { LoaderFunctionArgs } from '@remix-run/node';

import { auth } from '~/utils/auth.server';

export const loader = async ({ request }: LoaderFunctionArgs) => auth.authenticate('auth0', request, {
export const loader = async ({ request }: LoaderFunctionArgs) => auth.authenticate('oidc', request, {
successRedirect: '/private/profile',
failureRedirect: '/error',
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,27 @@
** All rights reserved
** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
*/
export const AUTH0_RETURN_TO_URL = process.env.AUTH0_RETURN_TO_URL!;
export const AUTH0_CALLBACK_URL = process.env.AUTH0_CALLBACK_URL!;
export const AUTH0_CLIENT_ID = process.env.AUTH0_CLIENT_ID!;
export const AUTH0_CLIENT_SECRET = process.env.AUTH0_CLIENT_SECRET!;
export const AUTH0_DOMAIN = process.env.AUTH0_DOMAIN!;
export const AUTH0_LOGOUT_URL = process.env.AUTH0_LOGOUT_URL!;
export const AUTH0_AUDIENCE = process.env.JWT_AUDIENCE!;
const AUTH0_BASE_URL = process.env.AUTH0_DOMAIN ? `https://${process.env.AUTH0_DOMAIN}` : '';

export const OIDC_RETURN_TO_URL = process.env.OIDC_RETURN_TO_URL || process.env.AUTH0_RETURN_TO_URL || 'http://localhost:3000';
export const OIDC_REDIRECT_URI = process.env.OIDC_REDIRECT_URI || process.env.AUTH0_CALLBACK_URL || '';
export const OIDC_CLIENT_ID = process.env.OIDC_CLIENT_ID || process.env.AUTH0_CLIENT_ID || '';
export const OIDC_CLIENT_SECRET = process.env.OIDC_CLIENT_SECRET || process.env.AUTH0_CLIENT_SECRET || '';
export const OIDC_AUTHORIZATION_ENDPOINT = process.env.OIDC_AUTHORIZATION_ENDPOINT
|| (AUTH0_BASE_URL ? `${AUTH0_BASE_URL}/authorize` : '');
export const OIDC_TOKEN_ENDPOINT = process.env.OIDC_TOKEN_ENDPOINT
|| (AUTH0_BASE_URL ? `${AUTH0_BASE_URL}/oauth/token` : '');
export const OIDC_USERINFO_ENDPOINT = process.env.OIDC_USERINFO_ENDPOINT
|| (AUTH0_BASE_URL ? `${AUTH0_BASE_URL}/userinfo` : '');
export const OIDC_LOGOUT_ENDPOINT = process.env.OIDC_LOGOUT_ENDPOINT || process.env.AUTH0_LOGOUT_URL || '';
export const OIDC_AUDIENCE = process.env.OIDC_AUDIENCE || process.env.JWT_AUDIENCE || '';
export const OIDC_SCOPES = process.env.OIDC_SCOPES
|| 'openid,email,profile,ords/sample-app/concert_app_authuser,ords/sample-app/concert_app_admin';
export const SCHEMA_NAME = process.env.SCHEMA_NAME || '';
export const { SCHEMA_PASSWORD } = process.env;
export const ADBS_ENDPOINT = process.env.ADB_ORDS_URL;
export const BASE_ENDPOINT = ADBS_ENDPOINT + SCHEMA_NAME.toLowerCase();
export const STATS_ENDPOINT = `${BASE_ENDPOINT}/euser/v1/landing_page_global_stats/`;
export const ADBS_ENDPOINT = process.env.BD_ORDS_URL;
export const BASE_ENDPOINT = ADBS_ENDPOINT;
export const STATS_ENDPOINT = `${BASE_ENDPOINT}/euser/v1/landing_page_global_stats`;
export const CITIES_ENDPOINT = `${BASE_ENDPOINT}/euser/v1/cities`;
export const EVENTS_ENDPOINT = `${BASE_ENDPOINT}/euser/v1/eventsHome`;
export const EVENT_ENDPOINT = `${BASE_ENDPOINT}/euser/v1/event`;
Expand Down
19 changes: 13 additions & 6 deletions templates/ords-remix-jwt-sample/app/routes/logout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,27 @@ import type { ActionFunctionArgs } from '@remix-run/node';
import { redirect } from '@remix-run/node';

import {
AUTH0_CLIENT_ID,
AUTH0_LOGOUT_URL,
AUTH0_RETURN_TO_URL,
OIDC_CLIENT_ID,
OIDC_LOGOUT_ENDPOINT,
OIDC_RETURN_TO_URL,
} from '~/routes/constants/index.server';
import {
destroySession, getSession,
} from '~/utils/auth.server';

export const action = async ({ request }: ActionFunctionArgs) => {
const session = await getSession(request.headers.get('Cookie'));
const logoutURL = new URL(AUTH0_LOGOUT_URL);
if (!OIDC_LOGOUT_ENDPOINT) {
return redirect(OIDC_RETURN_TO_URL, {
headers: {
'Set-Cookie': await destroySession(session),
},
});
}
const logoutURL = new URL(OIDC_LOGOUT_ENDPOINT);

logoutURL.searchParams.set('client_id', AUTH0_CLIENT_ID);
logoutURL.searchParams.set('returnTo', AUTH0_RETURN_TO_URL);
logoutURL.searchParams.set('client_id', OIDC_CLIENT_ID);
logoutURL.searchParams.set('post_logout_redirect_uri', OIDC_RETURN_TO_URL);

return redirect(logoutURL.toString(), {
headers: {
Expand Down
14 changes: 14 additions & 0 deletions templates/ords-remix-jwt-sample/app/routes/oidc.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
**
** Copyright (c) 2024, Oracle and/or its affiliates.
** All rights reserved
** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
*/
import type { ActionFunctionArgs } from '@remix-run/node';
import { redirect } from '@remix-run/node';

import { auth } from '~/utils/auth.server';

export const loader = async () => redirect('/');

export const action = async ({ request }: ActionFunctionArgs) => auth.authenticate('oidc', request);
6 changes: 3 additions & 3 deletions templates/ords-remix-jwt-sample/app/routes/sign-in.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Form } from '@remix-run/react';
import { ReactElement } from 'react';
/**
*
* @returns Sign In with Auth0
* @returns Sign In with OCI IAM
*/
export default function SignIn(): ReactElement {
return (
Expand All @@ -18,8 +18,8 @@ export default function SignIn(): ReactElement {
}}
>
<h1>Sign In</h1>
<Form action="../auth/auth0" method="post">
<button type="button">Login with Auth0</button>
<Form action="/oidc" method="post">
<button type="submit">Login with OCI IAM</button>
</Form>
</div>
);
Expand Down
Loading